-
Notifications
You must be signed in to change notification settings - Fork 0
/
PointerBoundObject.java
129 lines (106 loc) · 3.25 KB
/
PointerBoundObject.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.destranix.glslang;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public abstract class PointerBoundObject {
private static final Map<PointerBoundObject, PointerBoundObject> INSTANCES = new HashMap<PointerBoundObject, PointerBoundObject>();
protected static final String EXCEPTION_MSG_NOT_LOADABLE = "Cannot load element. Element was not created by constructor of this class";
protected static final String EXCEPTION_MSG_NOT_FREEABLE = "Cannot free element. Element was not created by constructor of this class";
protected byte[] ptr;
public void load() {
load_intern();
INSTANCES.put(this, this);
}
protected abstract void load_intern();
public void free() {
PointerBoundObject key = new PointerBoundObjectKey(ptr);
free_intern();
INSTANCES.remove(key);
}
protected abstract void free_intern();
protected byte[] getPtr() {
return ptr;
}
public <T extends PointerBoundObject> T cast(Class<T> instanceClass) {
return fromPtr(ptr, instanceClass);
}
@Override
public boolean equals(Object o) {
return ((o != null) && (o instanceof PointerBoundObject)
&& (this.ptr != null && ((PointerBoundObject) o).ptr != null)
&& (Arrays.equals(this.ptr, ((PointerBoundObject) o).ptr)));
}
@Override
public int hashCode() {
return Arrays.hashCode(ptr);
}
protected static PointerBoundObject fromPtr(byte[] ptr) {
if (ptr == null) {
return null;
}
boolean isNull = true;
for (int i = 0; i < ptr.length; ++i) {
if (ptr[i] != 0) {
isNull = false;
break;
}
}
if (isNull) {
return null;
}
return INSTANCES.get(new PointerBoundObjectKey(ptr));
}
protected static <T extends PointerBoundObject> T fromPtr(byte[] ptr, Class<T> instanceClass) {
if (ptr == null) {
return null;
}
boolean isNull = true;
for (int i = 0; i < ptr.length; ++i) {
if (ptr[i] != 0) {
isNull = false;
break;
}
}
if (isNull) {
return null;
}
PointerBoundObject obj = INSTANCES.get(new PointerBoundObjectKey(ptr));
T ret;
if (obj == null || PointerBoundObjectKey.class.equals(instanceClass)) {
try {
ret = instanceClass.getDeclaredConstructor(Byte.TYPE.arrayType()).newInstance(ptr);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new AssertionError("An error occured while instancing object.", e);
}
} else {
if (instanceClass.isAssignableFrom(obj.getClass())) {
ret = instanceClass.cast(obj);
} else {
throw new RuntimeException("Cannot cast elemnt to given type!");
}
}
return ret;
}
protected static PointerBoundObject fromPtrUndefined(byte[] ptr) {
return fromPtr(ptr, PointerBoundObjectKey.class);
}
protected static class PointerBoundObjectKey extends PointerBoundObject {
protected PointerBoundObjectKey(byte[] ptr) {
this.ptr = ptr;
}
@Override
public int hashCode() {
return Arrays.hashCode(ptr);
}
@Override
protected void load_intern() {
throw new IllegalStateException("Cannot load element of unknown type");
}
@Override
public void free_intern() {
throw new IllegalStateException("Cannot free element of unknown type");
}
}
}