1 package nom.tam.fits;
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 import java.io.IOException;
35
36 import nom.tam.util.ArrayDataInput;
37 import nom.tam.util.ArrayDataOutput;
38 import nom.tam.util.ByteArrayIO;
39 import nom.tam.util.FitsDecoder;
40 import nom.tam.util.FitsEncoder;
41
42
43
44
45
46
47 public class FitsHeap implements FitsElement {
48
49
50 private static final int MIN_HEAP_CAPACITY = 16384;
51
52
53
54
55
56
57 private ByteArrayIO store;
58
59
60 private FitsEncoder encoder;
61
62
63 private FitsDecoder decoder;
64
65
66
67
68 private FitsHeap() {
69 }
70
71
72
73
74
75
76
77
78 FitsHeap(int size) throws IllegalArgumentException {
79 if (size < 0) {
80 throw new IllegalArgumentException("Illegal size for FITS heap: " + size);
81 }
82
83 ByteArrayIO data = new ByteArrayIO(Math.max(size, MIN_HEAP_CAPACITY));
84 data.setLength(Math.max(0, size));
85 setData(data);
86 encoder = new FitsEncoder(store);
87 decoder = new FitsDecoder(store);
88 }
89
90
91
92
93
94
95 protected synchronized void setData(ByteArrayIO data) {
96 store = data;
97 }
98
99
100
101
102
103 synchronized FitsHeap copy() {
104 FitsHeap copy = new FitsHeap();
105 synchronized (copy) {
106 copy.setData(store.copy());
107 copy.encoder = new FitsEncoder(copy.store);
108 copy.decoder = new FitsDecoder(copy.store);
109 }
110 return copy;
111 }
112
113
114
115
116
117
118
119
120
121 public synchronized void getData(int offset, Object array) throws FitsException {
122 try {
123 store.position(offset);
124 decoder.readArrayFully(array);
125 } catch (Exception e) {
126 throw new FitsException("Error decoding heap area at offset=" + offset + ", size="
127 + FitsEncoder.computeSize(array) + " (heap size " + size() + "): " + e.getMessage(), e);
128 }
129 }
130
131 @Override
132 public long getFileOffset() {
133 throw new IllegalStateException("FitsHeap should only be reset from inside its parent, never alone");
134 }
135
136 @Override
137 public synchronized long getSize() {
138 return size();
139 }
140
141
142
143
144
145
146
147
148
149
150
151 synchronized long putData(Object data) throws FitsException {
152 return putData(data, store.length());
153 }
154
155
156
157
158
159
160
161
162
163
164
165
166 synchronized long putData(Object data, long pos) throws FitsException {
167 long lsize = pos + FitsEncoder.computeSize(data);
168 if (lsize > Integer.MAX_VALUE) {
169 throw new FitsException("FITS Heap > 2 G");
170 }
171
172 try {
173 store.position(pos);
174 encoder.writeArray(data);
175 } catch (Exception e) {
176 throw new FitsException("Unable to write variable column length data: " + e.getMessage(), e);
177 }
178
179 return store.position() - pos;
180 }
181
182
183
184
185
186
187
188
189
190
191 synchronized int copyFrom(FitsHeap src, int offset, int len) {
192 int pos = (int) store.length();
193 store.setLength(pos + len);
194 synchronized (src) {
195 System.arraycopy(src.store.getBuffer(), offset, store.getBuffer(), pos, len);
196 }
197 return pos;
198 }
199
200 @Override
201 public synchronized void read(ArrayDataInput str) throws FitsException {
202 if (store.length() == 0) {
203 return;
204 }
205
206 try {
207 str.readFully(store.getBuffer(), 0, (int) store.length());
208 } catch (IOException e) {
209 throw new FitsException("Error reading heap " + e.getMessage(), e);
210 }
211 }
212
213 @Override
214 public boolean reset() {
215 throw new IllegalStateException("FitsHeap should only be reset from inside its parent, never alone");
216 }
217
218 @Override
219 public void rewrite() throws IOException, FitsException {
220 throw new FitsException("FitsHeap should only be rewritten from inside its parent, never alone");
221 }
222
223 @Override
224 public boolean rewriteable() {
225 return false;
226 }
227
228
229
230
231
232
233 public synchronized int size() {
234 return (int) store.length();
235 }
236
237 @Override
238 public synchronized void write(ArrayDataOutput str) throws FitsException {
239 try {
240 str.write(store.getBuffer(), 0, (int) store.length());
241 } catch (IOException e) {
242 throw new FitsException("Error writing heap:" + e.getMessage(), e);
243 }
244 }
245
246 }