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 package org.jrobin.core;
27
28 import java.io.IOException;
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 public abstract class RrdBackend {
71 private static boolean instanceCreated = false;
72 private String path;
73
74
75
76
77
78
79
80
81 protected RrdBackend(String path) {
82 this.path = path;
83 instanceCreated = true;
84 }
85
86
87
88
89
90
91 public String getPath() {
92 return path;
93 }
94
95
96
97
98
99
100
101
102
103 protected abstract void write(long offset, byte[] b) throws IOException;
104
105
106
107
108
109
110
111
112
113 protected abstract void read(long offset, byte[] b) throws IOException;
114
115
116
117
118
119
120
121 public abstract long getLength() throws IOException;
122
123
124
125
126
127
128
129
130 protected abstract void setLength(long length) throws IOException;
131
132
133
134
135
136
137 public void close() throws IOException {
138 }
139
140
141
142
143
144
145
146
147
148
149 protected boolean isCachingAllowed() {
150 return true;
151 }
152
153
154
155
156
157
158
159 public final byte[] readAll() throws IOException {
160 byte[] b = new byte[(int) getLength()];
161 read(0, b);
162 return b;
163 }
164
165 final void writeInt(long offset, int value) throws IOException {
166 write(offset, getIntBytes(value));
167 }
168
169 final void writeLong(long offset, long value) throws IOException {
170 write(offset, getLongBytes(value));
171 }
172
173 final void writeDouble(long offset, double value) throws IOException {
174 write(offset, getDoubleBytes(value));
175 }
176
177 final void writeDouble(long offset, double value, int count) throws IOException {
178 byte[] b = getDoubleBytes(value);
179 byte[] image = new byte[8 * count];
180 for (int i = 0, k = 0; i < count; i++) {
181 image[k++] = b[0];
182 image[k++] = b[1];
183 image[k++] = b[2];
184 image[k++] = b[3];
185 image[k++] = b[4];
186 image[k++] = b[5];
187 image[k++] = b[6];
188 image[k++] = b[7];
189 }
190 write(offset, image);
191 }
192
193 final void writeDouble(long offset, double[] values) throws IOException {
194 int count = values.length;
195 byte[] image = new byte[8 * count];
196 for (int i = 0, k = 0; i < count; i++) {
197 byte[] b = getDoubleBytes(values[i]);
198 image[k++] = b[0];
199 image[k++] = b[1];
200 image[k++] = b[2];
201 image[k++] = b[3];
202 image[k++] = b[4];
203 image[k++] = b[5];
204 image[k++] = b[6];
205 image[k++] = b[7];
206 }
207 write(offset, image);
208 }
209
210 final void writeString(long offset, String value) throws IOException {
211 value = value.trim();
212 byte[] b = new byte[RrdPrimitive.STRING_LENGTH * 2];
213 for (int i = 0, k = 0; i < RrdPrimitive.STRING_LENGTH; i++) {
214 char c = (i < value.length()) ? value.charAt(i) : ' ';
215 byte[] cb = getCharBytes(c);
216 b[k++] = cb[0];
217 b[k++] = cb[1];
218 }
219 write(offset, b);
220 }
221
222 final int readInt(long offset) throws IOException {
223 byte[] b = new byte[4];
224 read(offset, b);
225 return getInt(b);
226 }
227
228 final long readLong(long offset) throws IOException {
229 byte[] b = new byte[8];
230 read(offset, b);
231 return getLong(b);
232 }
233
234 final double readDouble(long offset) throws IOException {
235 byte[] b = new byte[8];
236 read(offset, b);
237 return getDouble(b);
238 }
239
240 final double[] readDouble(long offset, int count) throws IOException {
241 int byteCount = 8 * count;
242 byte[] image = new byte[byteCount];
243 read(offset, image);
244 double[] values = new double[count];
245 for (int i = 0, k = -1; i < count; i++) {
246 byte[] b = new byte[] {
247 image[++k], image[++k], image[++k], image[++k],
248 image[++k], image[++k], image[++k], image[++k]
249 };
250 values[i] = getDouble(b);
251 }
252 return values;
253 }
254
255 final String readString(long offset) throws IOException {
256 byte[] b = new byte[RrdPrimitive.STRING_LENGTH * 2];
257 char[] c = new char[RrdPrimitive.STRING_LENGTH];
258 read(offset, b);
259 for (int i = 0, k = -1; i < RrdPrimitive.STRING_LENGTH; i++) {
260 byte[] cb = new byte[] {b[++k], b[++k]};
261 c[i] = getChar(cb);
262 }
263 return new String(c).trim();
264 }
265
266
267
268 private static byte[] getIntBytes(int value) {
269 byte[] b = new byte[4];
270 b[0] = (byte) ((value >>> 24) & 0xFF);
271 b[1] = (byte) ((value >>> 16) & 0xFF);
272 b[2] = (byte) ((value >>> 8) & 0xFF);
273 b[3] = (byte) ((value) & 0xFF);
274 return b;
275 }
276
277 private static byte[] getLongBytes(long value) {
278 byte[] b = new byte[8];
279 b[0] = (byte) ((int) (value >>> 56) & 0xFF);
280 b[1] = (byte) ((int) (value >>> 48) & 0xFF);
281 b[2] = (byte) ((int) (value >>> 40) & 0xFF);
282 b[3] = (byte) ((int) (value >>> 32) & 0xFF);
283 b[4] = (byte) ((int) (value >>> 24) & 0xFF);
284 b[5] = (byte) ((int) (value >>> 16) & 0xFF);
285 b[6] = (byte) ((int) (value >>> 8) & 0xFF);
286 b[7] = (byte) ((int) (value) & 0xFF);
287 return b;
288 }
289
290 private static byte[] getCharBytes(char value) {
291 byte[] b = new byte[2];
292 b[0] = (byte) ((value >>> 8) & 0xFF);
293 b[1] = (byte) ((value) & 0xFF);
294 return b;
295 }
296
297 private static byte[] getDoubleBytes(double value) {
298 return getLongBytes(Double.doubleToLongBits(value));
299 }
300
301 private static int getInt(byte[] b) {
302 assert b.length == 4: "Invalid number of bytes for integer conversion";
303 return ((b[0] << 24) & 0xFF000000) + ((b[1] << 16) & 0x00FF0000) +
304 ((b[2] << 8) & 0x0000FF00) + (b[3] & 0x000000FF);
305 }
306
307 private static long getLong(byte[] b) {
308 assert b.length == 8: "Invalid number of bytes for long conversion";
309 int high = getInt(new byte[] {b[0], b[1], b[2], b[3]});
310 int low = getInt(new byte[] {b[4], b[5], b[6], b[7]});
311 return ((long) (high) << 32) + (low & 0xFFFFFFFFL);
312 }
313
314 private static char getChar(byte[] b) {
315 assert b.length == 2: "Invalid number of bytes for char conversion";
316 return (char) (((b[0] << 8) & 0x0000FF00)
317 + (b[1] & 0x000000FF));
318 }
319
320 private static double getDouble(byte[] b) {
321 assert b.length == 8: "Invalid number of bytes for double conversion";
322 return Double.longBitsToDouble(getLong(b));
323 }
324
325 static boolean isInstanceCreated() {
326 return instanceCreated;
327 }
328 }