1 /* Copyright (c) 2007 Timothy Wall, All Rights Reserved
2  *
3  * The contents of this file is dual-licensed under 2
4  * alternative Open Source/Free licenses: LGPL 2.1 or later and
5  * Apache License 2.0. (starting with JNA version 4.0.0).
6  *
7  * You can freely decide which license you want to apply to
8  * the project.
9  *
10  * You may obtain a copy of the LGPL License at:
11  *
12  * http://www.gnu.org/licenses/licenses.html
13  *
14  * A copy is also included in the downloadable source code package
15  * containing JNA, in file "LGPL2.1".
16  *
17  * You may obtain a copy of the Apache License at:
18  *
19  * http://www.apache.org/licenses/
20  *
21  * A copy is also included in the downloadable source code package
22  * containing JNA, in file "AL2.0".
23  */
24 package com.sun.jna.ptr;
25 
26 import java.lang.reflect.Method;
27 
28 import com.sun.jna.Memory;
29 import com.sun.jna.Pointer;
30 import com.sun.jna.PointerType;
31 
32 /**
33  * Provides generic "pointer to type" functionality, often used in C code to
34  * return values to the caller in addition to a function result.
35  * <p>
36  * Derived classes must define <code>setValue(&lt;T&gt;)</code> and
37  * <code>&lt;T&gt; getValue()</code> methods which write to/read from the
38  * allocated memory.
39  * <p>
40  * This class derives from PointerType instead of Memory in order to restrict
41  * the API to only <code>getValue/setValue</code>.
42  * <p>
43  * NOTE: this class would ideally be replaced by a generic.
44  */
45 public abstract class ByReference extends PointerType {
46 
47     /**
48      * Allocates memory at this pointer, to contain the pointed-to value.
49      *
50      * @param dataSize
51      *            The number of bytes to allocate. Must match the byte size of
52      *            <code>T</code> in the derived class
53      *            <code>setValue(&lt;T&gt;)</code> and
54      *            <code>&lt;T&gt; getValue()</code> methods.
55      */
ByReference(int dataSize)56     protected ByReference(int dataSize) {
57         setPointer(new Memory(dataSize));
58     }
59 
60     @Override
toString()61     public String toString() {
62         try {
63             Method getValue = getClass().getMethod("getValue");
64             Object value = getValue.invoke(this);
65             if (value == null) {
66                 return String.format("null@0x%x", Pointer.nativeValue(getPointer()));
67             }
68             return String.format("%s@0x%x=%s", value.getClass().getSimpleName(), Pointer.nativeValue(getPointer()),
69                     value);
70         } catch (Exception ex) {
71             return String.format("ByReference Contract violated - %s#getValue raised exception: %s",
72                     getClass().getName(), ex.getMessage());
73         }
74     }
75 }
76