View Javadoc

1   /*
2   	Copyright (c) 2009 Olivier Chafik, All Rights Reserved
3   	
4   	This file is part of JNAerator (http://jnaerator.googlecode.com/).
5   	
6   	JNAerator is free software: you can redistribute it and/or modify
7   	it under the terms of the GNU Lesser General Public License as published by
8   	the Free Software Foundation, either version 3 of the License, or
9   	(at your option) any later version.
10  	
11  	JNAerator is distributed in the hope that it will be useful,
12  	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  	GNU Lesser General Public License for more details.
15  	
16  	You should have received a copy of the GNU Lesser General Public License
17  	along with JNAerator.  If not, see <http://www.gnu.org/licenses/>.
18  */
19  package com.ochafik.lang.jnaerator.runtime;
20  
21  import com.sun.jna.Memory;
22  import java.lang.ref.WeakReference;
23  import java.nio.Buffer;
24  
25  import com.sun.jna.Native;
26  import com.sun.jna.Pointer;
27  
28  public abstract class Union<S extends Union<S, V, R>, V extends S, R extends S> 
29  	extends com.sun.jna.Union
30  	implements
31  		StructureType,
32  		StructureTypeDependent
33  {	
34  	public interface ByReference extends com.sun.jna.Union.ByReference, StructureTypeDependent {}
35  	public interface ByValue extends com.sun.jna.Union.ByValue, StructureTypeDependent {}
36  
37  	transient WeakReference<StructureType> dependency;
38  	@Override
39  	public void setDependency(StructureType type) {
40  		this.dependency = type == null ? null : new WeakReference<StructureType>(type);
41  	}
42  	protected void readDependency() {
43  		StructureType dep;
44  		if (dependency == null || (dep = dependency.get()) == null)
45  			return;
46  		dep.read();
47  	}
48  	@Override
49  	public void read() {
50  		super.read();
51  		readDependency();
52  	}
53  	@Override
54  	public void write() {
55  		super.write();
56  		readDependency();
57  	}
58  	/**
59  	 * @deprecated use castToArray instead
60  	 */
61  	@Deprecated
62  	@SuppressWarnings("unchecked")
63  	@Override
64  	public S[] toArray(int size) {
65  		return (S[])super.toArray(size);
66  	}
67  	/**
68  	 * @deprecated use castToArray instead
69  	 */
70  	@Deprecated
71  	public S[] toArray() {
72  		return toArray(1);
73  	}
74  
75  	/**
76  	 * @deprecated use castToArray instead
77  	 */
78  	@Deprecated
79  	@SuppressWarnings("unchecked")
80  	@Override
81  	public S[] toArray(com.sun.jna.Structure[] array) {
82  		return (S[])super.toArray(array);
83  	}
84  
85  	@SuppressWarnings("unchecked")
86  	public S[] castToArray(int size) {
87  		return (S[])super.toArray(size);
88  	}
89  	public S[] castToArray() {
90  		return castToArray(1);
91  	}
92  	@SuppressWarnings("unchecked")
93  	public S[] castToArray(com.sun.jna.Structure[] array) {
94  		return (S[])super.toArray(array);
95  	}
96  
97  
98  	public static <S extends Union>
99  			S[] newArray(Class<S> structClass, int arrayLength) {
100 		try {
101 			S first = structClass.newInstance();
102 			int sz = first.size();
103 			Memory mem = new Memory(arrayLength * sz);
104 			first.use(mem);
105 			S[] array = (S[])first.castToArray(arrayLength);
106 			for (int i = 1; i < arrayLength; i++) {
107 				S s = structClass.newInstance();
108 				s.use(mem, i * sz);
109 				array[i] = s;
110 			}
111 			return array;
112 		} catch (Exception ex) {
113 			throw new RuntimeException(ex);
114 		}
115 	}
116 	
117 	protected abstract S newInstance();
118 	protected abstract V newByValue();
119 	protected abstract R newByReference();
120 	
121 	public R byReference() { return setupClone(newByReference()); }
122 	public V byValue() { return setupClone(newByValue()); }
123 	public S clone() { return setupClone(newInstance()); }
124 	
125 	protected <T extends Union<?, ?, ?>> T setupClone(T clone) {
126 		write();
127 		clone.use(getPointer());
128 		return clone;
129 	}
130 	
131 	public S use(Pointer m) {
132 		return use(m, 0);
133 	}
134 	public S use(Pointer m, long byteOffset) {
135 		useMemory(m, (int)byteOffset);
136 		return (S)this;
137 	}
138 	public S use(Buffer m) {
139 		return use(m, 0);
140 	}
141 	public S use(Buffer b, long byteOffset) {
142 		useMemory(Native.getDirectBufferPointer(b), (int)byteOffset);
143 		return (S)this;
144 	}
145 	
146 }