EMMA Coverage Report (generated Mon Mar 20 21:34:30 PST 2006)
[all classes][com.moesol.bindings]

COVERAGE SUMMARY FOR SOURCE FILE [NativeStructure.java]

nameclass, %method, %block, %line, %
NativeStructure.java100% (1/1)51%  (41/80)48%  (431/903)49%  (106.8/219)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class NativeStructure100% (1/1)51%  (41/80)48%  (431/903)49%  (106.8/219)
clearRecord (): void 0%   (0/1)0%   (0/12)0%   (0/4)
getBool (int): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
getBstr (int): String 0%   (0/1)0%   (0/5)0%   (0/1)
getByteSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getDouble (int): double 0%   (0/1)0%   (0/5)0%   (0/1)
getDoubleSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getFloat (int): float 0%   (0/1)0%   (0/5)0%   (0/1)
getFloatArray (int, int): float [] 0%   (0/1)0%   (0/21)0%   (0/5)
getFloatSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getIntArray (int, int): int [] 0%   (0/1)0%   (0/21)0%   (0/5)
getIntSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getInterface (int, Object []): void 0%   (0/1)0%   (0/39)0%   (0/10)
getLong (int): long 0%   (0/1)0%   (0/5)0%   (0/1)
getLongSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getShortArray (int, int): short [] 0%   (0/1)0%   (0/21)0%   (0/5)
getShortSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getSlice (int, long): ByteBuffer 0%   (0/1)0%   (0/26)0%   (0/3)
getStruct (int, int, NativeStructure): void 0%   (0/1)0%   (0/19)0%   (0/5)
getStructArray (int, int, int, NativeStructure []): void 0%   (0/1)0%   (0/32)0%   (0/8)
getUnsignedByteArray (int, int): short [] 0%   (0/1)0%   (0/25)0%   (0/5)
getUnsignedIntArray (int, int): long [] 0%   (0/1)0%   (0/28)0%   (0/6)
getUnsignedIntSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getUnsignedLongSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getUnsignedShortArray (int, int): char [] 0%   (0/1)0%   (0/27)0%   (0/6)
getUnsignedShortSize (): int 0%   (0/1)0%   (0/2)0%   (0/1)
getVariant (int): Object 0%   (0/1)0%   (0/6)0%   (0/1)
order (): ByteOrder 0%   (0/1)0%   (0/4)0%   (0/1)
order (ByteOrder): void 0%   (0/1)0%   (0/6)0%   (0/2)
putBool (int, boolean): void 0%   (0/1)0%   (0/9)0%   (0/2)
putBstr (int, String): void 0%   (0/1)0%   (0/9)0%   (0/2)
putFloat (int, float): void 0%   (0/1)0%   (0/7)0%   (0/2)
putFloatArray (int, int, float []): void 0%   (0/1)0%   (0/17)0%   (0/4)
putIntArray (int, int, int []): void 0%   (0/1)0%   (0/17)0%   (0/4)
putInterface (int, IUnknown): void 0%   (0/1)0%   (0/9)0%   (0/2)
putShortArray (int, int, short []): void 0%   (0/1)0%   (0/17)0%   (0/4)
putStructArray (int, int, int, NativeStructure []): void 0%   (0/1)0%   (0/19)0%   (0/4)
putVariant (int, Object): void 0%   (0/1)0%   (0/7)0%   (0/2)
stringFromC (byte []): String 0%   (0/1)0%   (0/6)0%   (0/1)
zero (): void 0%   (0/1)0%   (0/6)0%   (0/2)
_getStructureBytes (): byte [] 100% (1/1)62%  (8/13)67%  (2/3)
getString (int, int): String 100% (1/1)65%  (15/23)50%  (2/4)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
NativeStructure (ByteBuffer): void 100% (1/1)100% (14/14)100% (5/5)
NativeStructure (byte []): void 100% (1/1)100% (5/5)100% (2/2)
_getByteBuffer (): ByteBuffer 100% (1/1)100% (3/3)100% (1/1)
equals (Object): boolean 100% (1/1)100% (31/31)100% (10/10)
freeLpwstr (int): void 100% (1/1)100% (9/9)100% (3/3)
getArray (int, int): byte [] 100% (1/1)100% (14/14)100% (4/4)
getByte (int): byte 100% (1/1)100% (5/5)100% (1/1)
getByteArray (int, int): byte [] 100% (1/1)100% (14/14)100% (4/4)
getByteBuffer (): ByteBuffer 100% (1/1)100% (7/7)100% (1/1)
getInt (int): int 100% (1/1)100% (5/5)100% (1/1)
getLpwstr (int): String 100% (1/1)100% (5/5)100% (1/1)
getPointer (int): long 100% (1/1)100% (5/5)100% (1/1)
getRemaining (int): ByteBuffer 100% (1/1)100% (16/16)100% (4/4)
getShort (int): short 100% (1/1)100% (5/5)100% (1/1)
getSlice (int, int): ByteBuffer 100% (1/1)100% (17/17)100% (5/5)
getUnsignedByte (int): short 100% (1/1)100% (7/7)100% (1/1)
getUnsignedByteSize (): int 100% (1/1)100% (2/2)100% (1/1)
getUnsignedInt (int): long 100% (1/1)100% (7/7)100% (1/1)
getUnsignedShort (int): char 100% (1/1)100% (5/5)100% (1/1)
hashCode (): int 100% (1/1)100% (6/6)100% (2/2)
putArray (int, int, byte []): void 100% (1/1)100% (10/10)100% (3/3)
putByte (int, byte): void 100% (1/1)100% (7/7)100% (2/2)
putByteArray (int, int, byte []): void 100% (1/1)100% (10/10)100% (3/3)
putDouble (int, double): void 100% (1/1)100% (7/7)100% (2/2)
putInt (int, int): void 100% (1/1)100% (7/7)100% (2/2)
putLong (int, long): void 100% (1/1)100% (7/7)100% (2/2)
putLpwstr (int, String): void 100% (1/1)100% (9/9)100% (2/2)
putPointer (int, long): void 100% (1/1)100% (6/6)100% (2/2)
putShort (int, short): void 100% (1/1)100% (7/7)100% (2/2)
putString (int, int, String): void 100% (1/1)100% (15/15)100% (4/4)
putStruct (int, int, NativeStructure): void 100% (1/1)100% (19/19)100% (5/5)
putUnsignedByte (int, short): void 100% (1/1)100% (6/6)100% (2/2)
putUnsignedByteArray (int, int, short []): void 100% (1/1)100% (22/22)100% (4/4)
putUnsignedInt (int, long): void 100% (1/1)100% (6/6)100% (2/2)
putUnsignedIntArray (int, int, long []): void 100% (1/1)100% (25/25)100% (5/5)
putUnsignedShort (int, char): void 100% (1/1)100% (7/7)100% (2/2)
putUnsignedShortArray (int, int, char []): void 100% (1/1)100% (24/24)100% (5/5)
stringFromC (byte [], int, int): String 100% (1/1)100% (20/20)100% (3/3)

1/*
2 * $Id: NativeStructure.java,v 1.23 2006/02/09 21:32:34 hastings Exp $
3 *
4 * (c) Copyright, Moebius Solutions, Inc., 2004
5 *
6 *                       All Rights Reserved
7 *
8 * This material may be reproduced by or for the U. S. Government
9 * pursuant to the copyright license under the clause at
10 * DFARS 252.227-7014 (OCT 2001).
11 */
12 
13package com.moesol.bindings;
14 
15import java.nio.ByteBuffer;
16import java.nio.ByteOrder;
17import java.nio.CharBuffer;
18import java.nio.FloatBuffer;
19import java.nio.IntBuffer;
20import java.nio.ShortBuffer;
21import java.util.Arrays;
22 
23import com.moesol.bindings.platform_sdk.component_services.COMException;
24import com.moesol.bindings.platform_sdk.component_services.HRESULT;
25import com.moesol.bindings.platform_sdk.component_services.IUnknown;
26import com.moesol.bindings.platform_sdk.component_services.InterfaceBuilder;
27import com.moesol.bindings.platform_sdk.component_services.VARIANT;
28 
29 
30/**
31 * Wraps the bytes of a native structure with a java class that
32 * allows easier access to the java compatible values of structure
33 * fields at given offsets. A union is treated in the same way 
34 * as a structure, but the offsets to the fields may be the same.
35 * For example, the may all be at zero. Nested structures are supported
36 * by creating slices. Since the slices refer to the same underlying
37 * bytes when a nested structure is changed through the java wrapper
38 * so is the outer structure. However, primitive arrays are copied.
39 * 
40 * @author Robert Hastings
41 */
42public class NativeStructure {
43        
44    protected NativeStructure(byte[] bytes) {
45        this(ByteBuffer.wrap(bytes));
46    }
47    protected NativeStructure(ByteBuffer bb) {
48        m_byte_buffer = bb;
49        m_byte_buffer.order(ByteOrder.nativeOrder());
50    }
51    
52    /**
53         * Allow the native order to be overriden for byte swapped files.
54         * 
55         * @param bo
56         *            The new byte order.
57         */
58    public void order(ByteOrder bo) {
59            m_byte_buffer.order(bo);
60    }
61    /**
62         * Get the byte order for this structure.
63         * 
64         * @return ByteOrder
65         */
66    public ByteOrder order() {
67            return m_byte_buffer.order();
68    }
69    
70    /** Fill the structure with zeros */
71        public void zero() {
72                Arrays.fill(m_byte_buffer.array(), (byte) 0);
73        }
74        
75    protected void putLong(int offset, long v) {
76            m_byte_buffer.putLong(offset, v);
77    }
78    protected long getLong(int offset) {
79            return m_byte_buffer.getLong(offset);
80    }
81    
82    protected void putInt(int offset, int v) {
83        m_byte_buffer.putInt(offset, v);
84    }
85    protected int getInt(int offset) {
86        return m_byte_buffer.getInt(offset);
87    }
88    protected void putUnsignedInt(int offset, long v) {
89            putInt(offset, (int)v);
90    }
91    protected long getUnsignedInt(int offset) {
92            return getInt(offset) & 0xFFFFFFFFL;
93    }
94    
95    protected void putBool(int offset, boolean v) {
96        putShort(offset, v ? (short)-1 : 0);
97    }
98    protected boolean getBool(int offset) {
99        return getShort(offset) == 0 ? false : true;
100    }
101    protected void putShort(int offset, short v) {
102        m_byte_buffer.putShort(offset, v);
103    }
104    protected short getShort(int offset) {
105        return m_byte_buffer.getShort(offset);
106    }
107    protected void putUnsignedShort(int offset, char v) {
108            m_byte_buffer.putChar(offset, v);
109    }
110    protected char getUnsignedShort(int offset) {
111            return m_byte_buffer.getChar(offset);
112    }
113    
114    protected void putByte(int offset, byte v) {
115        m_byte_buffer.put(offset, v);
116    }
117    protected byte getByte(int offset) {
118        return m_byte_buffer.get(offset);
119    }
120    protected void putUnsignedByte(int offset, short v) {
121            putByte(offset, (byte)v);
122    }
123    protected short getUnsignedByte(int offset) {
124            return (short) (getByte(offset) & 0xFF);
125    }
126    
127        protected void putDouble(int offset, double v) {
128                m_byte_buffer.putDouble(offset, v);
129        }
130        protected double getDouble(int offset) {
131                return m_byte_buffer.getDouble(offset);
132        }
133        
134        protected void putFloat(int offset, float v) {
135                m_byte_buffer.putFloat(offset, v);
136        }
137        protected float getFloat(int offset) {
138                return m_byte_buffer.getFloat(offset);
139        }
140        
141    protected void putString(int offset, int buflen, String v) {
142        ByteBuffer bb = getSlice(offset, buflen);
143        bb.put(v.getBytes());
144        bb.put((byte)0);
145    }
146    protected String getString(int offset, int buflen) {
147        if (m_byte_buffer.hasArray()) {
148                return stringFromC(m_byte_buffer.array(),
149                                                           m_byte_buffer.arrayOffset() + offset, buflen);
150        }
151        
152        byte[] array = getArray(offset, buflen);
153        return stringFromC(array);
154    }
155    
156    /**
157     * Turn an array of bytes that is a C '\0' terminated string
158     * into a java string.
159     * 
160     * @return java string from a C string.
161     */
162    public static String stringFromC(byte[] s) {
163            return stringFromC(s, 0, s.length);
164    }
165    
166    /**
167     * Turn an array of bytes that is a C '\0' terminated string
168     * into a java string.
169     * 
170     * @param s
171     * @param offset
172     * @param length
173     * 
174     * @return java string from a C string.
175     */
176    public static String stringFromC(byte[] s, int offset, int length) {
177            int i = 0;
178            for (; i < length && s[offset + i] != 0; i++) {
179            }
180            return new String(s, offset, i);
181    }
182    
183    /**
184     * Copies v into this structure.
185     * 
186     * @param offset
187     * @param buflen
188     * @param v
189     */
190    protected void putArray(int offset, int buflen, byte[] v) {
191        ByteBuffer bb = getSlice(offset, buflen);
192        bb.put(v);
193    }
194    /**
195     * Gets a copy of the array. Modifying the returned array
196     * has no effect on the structure.
197     * @param offset
198     * @param buflen
199     * @return copy of sub-array
200     */
201    protected byte[] getArray(int offset, int buflen) {
202        byte[] result = new byte[buflen];
203        ByteBuffer bb = getSlice(offset, buflen);
204        bb.get(result);
205        return result;
206    }
207 
208    protected void putByteArray(int offset, int buflen, byte[] v) {
209        ByteBuffer bb = getSlice(offset, buflen);
210        bb.put(v);
211    }
212    /**
213     * Gets a copy of the array. Modifying the returned array
214     * has no effect on the structure.
215     * @param offset
216     * @param buflen
217     * @return copy of sub-array.
218     */
219    protected byte[] getByteArray(int offset, int buflen) {
220        byte[] result = new byte[buflen];
221        ByteBuffer bb = getSlice(offset, buflen);
222        bb.get(result);
223        return result;
224    }
225 
226    /**
227     * Copies the array into this struct in native byte order and packing.
228     * 
229         * @param offset
230         * @param count
231         * @param v
232         */
233        protected void putUnsignedIntArray(int offset, int count, long[] v) {
234                ByteBuffer bb = getSlice(offset, 4 * count);
235                IntBuffer ib = bb.asIntBuffer();
236                for (int i = 0; i < count; i++) {
237                        ib.put((int)v[i]);
238                }
239        }
240        
241        /**
242     * Gets a copy of the array. Modifying the returned array
243     * has no effect on the structure.
244         * 
245         * @param offset
246         * @param count
247         * @return a new array that is a copy of the values in the struct.
248         */
249        protected long[] getUnsignedIntArray(int offset, int count) {
250                ByteBuffer bb = getSlice(offset, 4 * count);
251                IntBuffer ib = bb.asIntBuffer();
252                long[] result = new long[count];
253                for (int i = 0; i < count; i++) {
254                        result[i] = ib.get();
255                }
256                return result;
257        }
258        
259    protected void putShortArray(int offset, int count, short[] v) {
260        ByteBuffer bb = getSlice(offset, getShortSize() * count);
261        ShortBuffer sb = bb.asShortBuffer();
262        sb.put(v, 0, count);
263    }
264    protected short[] getShortArray(int offset, int count) {
265        ByteBuffer bb = getSlice(offset, getShortSize() * count);
266        short[] result = new short[count];
267        ShortBuffer sb = bb.asShortBuffer();
268        sb.get(result, 0, count);
269        return result;
270    }
271    protected void putIntArray(int offset, int count, int[] v) {
272        ByteBuffer bb = getSlice(offset, getIntSize() * count);
273        IntBuffer ib = bb.asIntBuffer();
274        ib.put(v, 0, count);
275    }
276    protected int[] getIntArray(int offset, int count) {
277        ByteBuffer bb = getSlice(offset, getIntSize() * count);
278        int[] result = new int[count];
279        IntBuffer ib = bb.asIntBuffer();
280        ib.get(result, 0, count);
281        return result;
282    }
283    protected void putFloatArray(int offset, int count, float[] v) {
284        ByteBuffer bb = getSlice(offset, getFloatSize() * count);
285        FloatBuffer fb = bb.asFloatBuffer();
286        fb.put(v, 0, count);
287    }
288    protected float[] getFloatArray(int offset, int count) {
289        ByteBuffer bb = getSlice(offset, getFloatSize() * count);
290        float[] result = new float[count];
291        FloatBuffer fb = bb.asFloatBuffer();
292        fb.get(result, 0, count);
293        return result;
294    }
295    
296    /**
297     * Copies the array into this struct in native byte order and packing.
298     * 
299         * @param offset
300         * @param count
301         * @param v
302         */
303        protected void putUnsignedShortArray(int offset, int count, char[] v) {
304                ByteBuffer bb = getSlice(offset, 2 * count);
305                CharBuffer cb = bb.asCharBuffer();
306                for (int i = 0; i < count; i++) {
307                        cb.put(v[i]);
308                }
309        }
310        
311        /**
312     * Gets a copy of the array. Modifying the returned array
313     * has no effect on the structure.
314         * 
315         * @param offset
316         * @param count
317         * @return a new array that is a copy of the values in the struct.
318         */
319        protected char[] getUnsignedShortArray(int offset, int count) {
320                ByteBuffer bb = getSlice(offset, 2 * count);
321                CharBuffer cb = bb.asCharBuffer();
322                char[] result = new char[count];
323                for (int i = 0; i < count; i++) {
324                        result[i] = cb.get();
325                }
326                return result;
327        }
328 
329        /**
330     * Copies the array into this struct in native byte order and packing.
331     * 
332         * @param offset
333         * @param count
334         * @param v
335         */
336        protected void putUnsignedByteArray(int offset, int count, short[] v) {
337                ByteBuffer bb = getSlice(offset, 1 * count);
338                for (int i = 0; i < count; i++) {
339                        bb.put((byte)v[i]);
340                }
341        }
342    /**
343     * Gets a copy of the array. Modifying the returned array
344     * has no effect on the structure.
345     * 
346         * @param offset
347         * @param count
348         * @return a new array that is a copy of the values in the struct.
349         */
350        protected short[] getUnsignedByteArray(int offset, int count) {
351                ByteBuffer bb = getSlice(offset, 1 * count);
352                short[] result = new short[count];
353                for (int i = 0; i < count; i++) {
354                        result[i] = bb.get();
355                }
356                return result;
357        }
358        
359        /**
360         * Gets a slice of the byte buffer that is all bytes after
361         * offset. It is expected that the callee will adjust the
362         * limit of the byte buffer to match the structure size. This method
363         * allows for structures that contain variable sized arrays.
364         * 
365         * @param offset
366         * @return slice of remaining bytes.
367         */
368        protected ByteBuffer getRemaining(int offset) {
369                ByteBuffer dup = m_byte_buffer.duplicate();
370                dup.position(offset);
371                dup.limit(dup.capacity()); // open up the tail bytes
372                return dup.slice();
373        }
374    
375    /**
376     * Gets a slice of the array. Modifying the returned slice
377     * modifies the underlying structure as well.
378     * 
379     * @param offset start offset of slice
380     * @param length length of slice
381     * @return new slice
382     */
383    protected ByteBuffer getSlice(int offset, int length) {
384                ByteBuffer dup = m_byte_buffer.duplicate();
385        dup.position(offset);
386                ByteBuffer slice = dup.slice();
387                slice.limit(length);
388                return slice;
389    }
390    /**
391     * Pass along a ULONG to getSlice as an int
392     * @param offset
393     * @param length
394     */
395    protected ByteBuffer getSlice(int offset, long length) {
396            assert(length >= 0);
397            assert(length < Integer.MAX_VALUE);
398            return getSlice(offset, (int)length);
399    }
400    
401    /**
402     * Copy s into a sub-structure of this.
403     * 
404     * @param offset
405     * @param length
406     * @param s
407     */
408    protected void putStruct(int offset, int length, NativeStructure s) {
409            ByteBuffer src = s._getByteBuffer().duplicate();
410            ByteBuffer dst = getSlice(offset, length);
411            while (src.hasRemaining()) {
412                    dst.put(src.get());
413            }
414    }
415    /**
416     * Copy the sub-structure into s
417     * 
418     * @param offset
419     * @param length
420     * @param s
421     */
422    protected void getStruct(int offset, int length, NativeStructure s) {
423            ByteBuffer src = getSlice(offset, length);
424            ByteBuffer dst = s._getByteBuffer().duplicate();
425            while (src.hasRemaining()) {
426                    dst.put(src.get());
427            }
428    }
429    
430    protected void putInterface(int offset, IUnknown unk) {
431        putPointer(offset, jni_putInterface(getPointer(offset), unk));
432    }
433    
434    protected void getInterface(int offset, Object[] out) {
435            long raw_ptr = getPointer(offset);
436            if (raw_ptr == 0) {
437                    out[0] = null;
438                    return;
439            }
440            
441        InterfaceBuilder ib = new InterfaceBuilder(out);
442        int hr = jni_getInterface(raw_ptr, ib.getIIDBytes(), ib.getResult());
443        if (HRESULT.FAILED(hr)) {
444            throw new COMException(hr);
445        }
446        out[0] = ib.getResult();
447    }
448    
449    protected void putVariant(int offset, Object v) {
450            jni_putVariant(getSlice(offset, VARIANT.sizeof()), v);
451    }
452        protected Object getVariant(int offset) {
453            return jni_getVariant(getSlice(offset, VARIANT.sizeof()));
454    }
455    
456        protected void putBstr(int offset, String v) {
457            putPointer(offset, jni_putBstr(getPointer(offset), v));
458    }
459    protected String getBstr(int offset) {
460            return jni_getBstr(getPointer(offset));
461    }
462 
463        protected void putLpwstr(int offset, String v) {
464            putPointer(offset, jni_putLpwstr(getPointer(offset), v));
465    }
466    protected String getLpwstr(int offset) {
467            return jni_getLpwstr(getPointer(offset));
468    }
469    protected void freeLpwstr(int offset) {
470            jni_freeLpwstr(getPointer(offset));
471            putPointer(offset, 0);
472    }
473 
474    // TODO support for 64 bit pointer?
475    private void putPointer(int offset, long ptr) {
476            putInt(offset, (int)ptr);
477    }
478    private long getPointer(int offset) {
479            return getInt(offset);
480    }
481    
482    /** @return raw BSTR pointer */
483    private native static long jni_putBstr(long old_raw_bstr, String v);
484    /** @return converted string */
485    private native static String jni_getBstr(long raw_bstr);
486    /** @return raw LPWSTR pointer */
487    private native static long jni_putLpwstr(long old_raw_lpwstr, String v);
488    /** @return converted string */
489    private native static String jni_getLpwstr(long raw_lpwstr);
490    /** free string */
491    private native static void jni_freeLpwstr(long raw_lpwstr);
492    /** @return raw Interface */
493    private native static long jni_putInterface(long old_iface_ptr, IUnknown unk);
494    /** @return HRESULT */
495    private native static int jni_getInterface(long iface_ptr, byte[] iid_bytes, IUnknown result);
496    /** convert v to a raw VARIANT structure */
497    private native static void jni_putVariant(ByteBuffer vs, Object v);
498    /**
499     * Convert raw VARIANT to best Java Object
500     * @return VARIANT as Java object.
501     */
502    private native static Object jni_getVariant(ByteBuffer vs);
503    /** @return HRESULT */
504    private native int jni_clearRecord();
505    
506    /**
507     * NativeStructures that contain fields of type BSTR, VARIANT, SAFEARRAY, or
508     * COM Interface must call clearRecord or native resources will be leaked.
509     * NativeStructure subclasses generated by tlb2java that contain such fields
510     * have a finalize method generated that calls clearRecord. However, you may
511     * call clearRecord whenever you no longer need the NativeStructure to free
512     * resources.
513     */
514    public void clearRecord() {
515        int hr;
516        hr = jni_clearRecord();
517        if (HRESULT.FAILED(hr)) {
518            throw new COMException(hr);
519        }
520    }
521 
522        /**
523         * Copy v into this structure
524         * 
525         * @param offset
526         * @param size
527         * @param count
528         * @param v
529         */
530        protected void putStructArray(int offset, int size, int count, NativeStructure[] v) {
531                for (int i = 0; i < count; i++) {
532                        putStruct(offset, size, v[i]);
533                        offset += size;
534                }
535        }
536        /**
537         * Copy the array sub-structures into v.
538         * 
539         * @param offset
540         * @param size
541         * @param count
542         * @param v
543         */
544        protected void getStructArray(int offset, int size, int count, NativeStructure[] v) {
545                try {
546                        Class cls = v.getClass().getComponentType();
547                        for (int i = 0; i < count; i++) {
548                                v[i] = (NativeStructure)cls.newInstance();
549                                getStruct(offset, size, v[i]);
550                        }
551                } catch (Exception e) {
552                        throw new RuntimeException(e);
553                }
554        }
555    
556    /**
557         * JNI support
558         * 
559         * @return the byte array which contains the bytes of the structure.
560         */
561    public byte[] _getStructureBytes() {
562        if (m_byte_buffer.arrayOffset() != 0) {
563            throw new IllegalStateException("Cannot get structure bytes for a nested structure");
564        }
565        return m_byte_buffer.array();
566    }
567    /**
568         * JUnit support
569         * 
570         * @return the byte buffer which contains the bytes of the structure.
571         */
572    public ByteBuffer _getByteBuffer() {
573        return m_byte_buffer;
574    }
575    
576//    private int findNullByte(int offset, int buflen) {
577//        m_byte_buffer.position(offset);
578//        int result = 0;
579//        while (result < buflen) {
580//            if (m_byte_buffer.get() == 0) {
581//                break;
582//            }
583//            result++;
584//        }
585//        m_byte_buffer.position(0);
586//        return result;
587//    }
588    
589    /**
590     * Tells whether or not this structure is equal to another structure.
591     * The classes of the structures must be the same and their byte buffers
592     * must also be equal.
593     * 
594     * @return true if two have structures are the same.
595     */
596        public boolean equals(Object other) {
597                if (this == other) {
598                        return true;
599                }
600                if (null == other) {
601                        return false;
602                }
603                if (!getClass().equals(other.getClass())) {
604                        return false;
605                }
606                NativeStructure ns_other = (NativeStructure)other;
607                ByteBuffer my_bb = getByteBuffer();
608                ByteBuffer other_bb = ns_other.getByteBuffer();
609                return my_bb.equals(other_bb);
610        }
611        
612        /**
613         * Gets the byte buffer used as this structures underlying storage.
614         * Changing the returned buffer changes the structure values.
615         * However, the returned buffer is a duplicate byte buffer so
616         * changes to the position, mark, and limit do not affect the internal
617         * buffer. _getByteBuffer is slightly more efficient, but
618         * the position is not guaranteed to be 0. 
619         * 
620         * @return the byte buffer used as this structures underlying storage.
621         */
622        public ByteBuffer getByteBuffer() {
623                return (ByteBuffer)m_byte_buffer.duplicate().position(0);
624        }
625        
626        /**
627         * Computes the hash of the bytes of this native structure.
628         * The underlying byte buffer may be direct or indirect.
629         * 
630         * @return the computed hash of the bytes of the native structure.
631         */
632        public int hashCode() {
633                ByteBuffer bb = getByteBuffer();
634                return bb.hashCode();
635        }
636        
637        public static int getByteSize() {
638                return 1;
639        }
640        public static int getUnsignedByteSize() {
641                return 1;
642        }
643        public static int getShortSize() {
644                return 2;
645        }
646        public static int getUnsignedShortSize() {
647                return 2;
648        }
649        public static int getIntSize() {
650                return 4;
651        }
652        public static int getUnsignedIntSize() {
653                return 4;
654        }
655        /**
656         * Number of bytes in a C/C++ 32 bit long.
657         *
658         * @return size of a long in MSVC 
659         */
660        public static int getLongSize() {
661                return 4;
662        }
663        public static int getUnsignedLongSize() {
664                return 4;
665        }
666        public static int getFloatSize() {
667                return 4;
668        }
669        public static int getDoubleSize() {
670                return 8;
671        }
672        
673        private ByteBuffer m_byte_buffer = null; // usually a non-direct byte buffer
674}

[all classes][com.moesol.bindings]
EMMA 2.0.5312 (C) Vladimir Roubtsov