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