b381995365983a790e50908913a779465190e8d8
[public/netxms.git] / src / java / netxms-base / src / main / java / org / netxms / base / NXCPVariable.java
1 package org.netxms.base;
2
3 import java.io.*;
4 import java.net.*;
5 import java.util.Arrays;
6 import java.util.UUID;
7
8 /**
9 * @author victor
10 */
11 public class NXCPVariable
12 {
13 public static final int TYPE_INTEGER = 0;
14 public static final int TYPE_STRING = 1;
15 public static final int TYPE_INT64 = 2;
16 public static final int TYPE_INT16 = 3;
17 public static final int TYPE_BINARY = 4;
18 public static final int TYPE_FLOAT = 5;
19
20 private long variableId;
21 private int variableType;
22
23 private Long integerValue;
24 private Double realValue;
25 private String stringValue;
26 private byte[] binaryValue;
27
28 /* (non-Javadoc)
29 * @see java.lang.Object#toString()
30 */
31 @Override
32 public String toString()
33 {
34 StringBuilder result = new StringBuilder();
35 String NEW_LINE = System.getProperty("line.separator");
36
37 result.append(this.getClass().getName() + " Object {" + NEW_LINE);
38 result.append(" variableId = " + Long.toString(variableId) + NEW_LINE);
39 result.append(" variableType = " + variableType + NEW_LINE);
40 result.append(" integerValue = " + integerValue + NEW_LINE);
41 result.append(" realValue = " + realValue + NEW_LINE);
42 result.append(" stringValue = " + stringValue + NEW_LINE);
43 result.append(" binaryValue = " + Arrays.toString(binaryValue) + NEW_LINE);
44 result.append("}");
45
46 return result.toString();
47 }
48
49 /**
50 * Set string value and numeric values if possible
51 *
52 * @param value New string value
53 */
54 private void setStringValue(String value)
55 {
56 stringValue = (value != null) ? value : "";
57 try
58 {
59 integerValue = Long.parseLong(stringValue);
60 }
61 catch (NumberFormatException e)
62 {
63 integerValue = 0L;
64 }
65 try
66 {
67 realValue = Double.parseDouble(stringValue);
68 }
69 catch (NumberFormatException e)
70 {
71 realValue = (double)0;
72 }
73 }
74
75 /**
76 * @param varId
77 * @param varType
78 * @param value
79 */
80 public NXCPVariable(final long varId, final int varType, final Long value)
81 {
82 variableId = varId;
83 variableType = varType;
84 integerValue = value;
85 stringValue = integerValue.toString();
86 realValue = integerValue.doubleValue();
87 }
88
89 /**
90 * @param varId
91 * @param value
92 */
93 public NXCPVariable(final long varId, final String value)
94 {
95 variableId = varId;
96 variableType = TYPE_STRING;
97 setStringValue(value);
98 }
99
100 /**
101 * @param varId
102 * @param value
103 */
104 public NXCPVariable(final long varId, final Double value)
105 {
106 variableId = varId;
107 variableType = TYPE_FLOAT;
108 realValue = value;
109 stringValue = value.toString();
110 integerValue = realValue.longValue();
111 }
112
113 /**
114 * @param varId
115 * @param value
116 */
117 public NXCPVariable(final long varId, final byte[] value)
118 {
119 variableId = varId;
120 variableType = TYPE_BINARY;
121 binaryValue = value;
122 stringValue = "";
123 integerValue = (long)0;
124 realValue = (double)0;
125 }
126
127 /**
128 * Create binary variable from long[]
129 *
130 * @param varId Variable ID
131 * @param value Value
132 */
133 public NXCPVariable(final long varId, final long[] value)
134 {
135 variableId = varId;
136 variableType = TYPE_BINARY;
137
138 final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(value.length * 4);
139 final DataOutputStream out = new DataOutputStream(byteStream);
140 try
141 {
142 for(int i = 0; i < value.length; i++)
143 out.writeInt((int)value[i]);
144 }
145 catch(IOException e)
146 {
147 }
148 binaryValue = byteStream.toByteArray();
149 stringValue = "";
150 integerValue = (long)0;
151 realValue = (double)0;
152 }
153
154 /**
155 * Create binary variable from Long[]
156 *
157 * @param varId Variable ID
158 * @param value Value
159 */
160 public NXCPVariable(final long varId, final Long[] value)
161 {
162 variableId = varId;
163 variableType = TYPE_BINARY;
164
165 final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(value.length * 4);
166 final DataOutputStream out = new DataOutputStream(byteStream);
167 try
168 {
169 for(int i = 0; i < value.length; i++)
170 out.writeInt(value[i].intValue());
171 }
172 catch(IOException e)
173 {
174 }
175 binaryValue = byteStream.toByteArray();
176 stringValue = "";
177 integerValue = (long)0;
178 realValue = (double)0;
179 }
180
181 /**
182 * @param varId
183 * @param value
184 */
185 public NXCPVariable(final long varId, final InetAddress value)
186 {
187 variableId = varId;
188 variableType = TYPE_INTEGER;
189
190 byte[] addr = value.getAddress();
191 integerValue = ((long)(addr[0] & 0xFF) << 24) | ((long)(addr[1] & 0xFF) << 16) | ((long)(addr[2] & 0xFF) << 8) | (long)(addr[3] & 0xFF);
192 realValue = integerValue.doubleValue();
193 stringValue = integerValue.toString();
194 }
195
196 /**
197 * @param varId
198 * @param value
199 */
200 public NXCPVariable(final long varId, final UUID value)
201 {
202 variableId = varId;
203 variableType = TYPE_BINARY;
204
205 final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(16);
206 final DataOutputStream out = new DataOutputStream(byteStream);
207 try
208 {
209 out.writeLong(value.getMostSignificantBits());
210 out.writeLong(value.getLeastSignificantBits());
211 }
212 catch(IOException e)
213 {
214 }
215 binaryValue = byteStream.toByteArray();
216 stringValue = "";
217 integerValue = (long)0;
218 realValue = (double)0;
219 }
220
221 /**
222 * Create NXCPVariable from NXCP message data field
223 *
224 * @param nxcpDataField
225 * @throws java.io.IOException
226 */
227 public NXCPVariable(final byte[] nxcpDataField) throws IOException
228 {
229 NXCPDataInputStream in = new NXCPDataInputStream(nxcpDataField);
230
231 variableId = (long)in.readUnsignedInt();
232 variableType = in.readUnsignedByte();
233 in.skipBytes(1); // Skip padding
234 if (variableType == TYPE_INT16)
235 {
236 integerValue = (long)in.readUnsignedShort();
237 realValue = integerValue.doubleValue();
238 stringValue = integerValue.toString();
239 }
240 else
241 {
242 in.skipBytes(2);
243 switch(variableType)
244 {
245 case TYPE_INTEGER:
246 integerValue = (long)in.readUnsignedInt();
247 realValue = integerValue.doubleValue();
248 stringValue = integerValue.toString();
249 break;
250 case TYPE_INT64:
251 integerValue = in.readLong();
252 realValue = integerValue.doubleValue();
253 stringValue = integerValue.toString();
254 break;
255 case TYPE_FLOAT:
256 realValue = in.readDouble();
257 integerValue = realValue.longValue();
258 stringValue = realValue.toString();
259 break;
260 case TYPE_STRING:
261 int len = in.readInt() / 2;
262 StringBuilder sb = new StringBuilder(len);
263 while (len > 0)
264 {
265 sb.append(in.readChar());
266 len--;
267 }
268 setStringValue(sb.toString());
269 break;
270 case TYPE_BINARY:
271 binaryValue = new byte[in.readInt()];
272 in.readFully(binaryValue);
273 break;
274 }
275 }
276 }
277
278 /**
279 * Get variable's value as long integer
280 *
281 * @return Variable's value as long integer
282 */
283 public Long getAsInteger()
284 {
285 return integerValue;
286 }
287
288 /**
289 * Get variable's value as floating point number
290 *
291 * @return Variable's value as floating point number
292 */
293 public Double getAsReal()
294 {
295 return realValue;
296 }
297
298 /**
299 * Get variable's value as string
300 *
301 * @return Variable's value as string
302 */
303 public String getAsString()
304 {
305 return stringValue;
306 }
307
308 /**
309 * Get variable's value as byte array
310 *
311 * @return Variable's value as byte array
312 */
313 public byte[] getAsBinary()
314 {
315 return binaryValue;
316 }
317
318 /**
319 * Get variable's value as IP address
320 *
321 * @return Variable's value as IP address
322 */
323 public InetAddress getAsInetAddress()
324 {
325 final byte[] addr = new byte[4];
326 final long intVal = integerValue.longValue();
327 InetAddress inetAddr;
328
329 addr[0] = (byte)((intVal & 0xFF000000) >> 24);
330 addr[1] = (byte)((intVal & 0x00FF0000) >> 16);
331 addr[2] = (byte)((intVal & 0x0000FF00) >> 8);
332 addr[3] = (byte)(intVal & 0x000000FF);
333
334 try
335 {
336 inetAddr = InetAddress.getByAddress(addr);
337 }
338 catch(UnknownHostException e)
339 {
340 inetAddr = null;
341 }
342 return inetAddr;
343 }
344
345 /**
346 * Get variable's value as UUID
347 *
348 * @return Variable's value as UUID
349 */
350 public UUID getAsUUID()
351 {
352 if ((variableType != TYPE_BINARY) || (binaryValue == null) || (binaryValue.length != 16))
353 return null;
354
355 NXCPDataInputStream in = new NXCPDataInputStream(binaryValue);
356 long hiBits, loBits;
357 try
358 {
359 hiBits = in.readLong();
360 loBits = in.readLong();
361 }
362 catch(IOException e)
363 {
364 hiBits = 0;
365 loBits = 0;
366 }
367
368 return new UUID(hiBits, loBits);
369 }
370
371 /**
372 * Get variable's value as array of long integers. Variable should be of
373 * binary type, and integer values should be packet as DWORD's in network byte order.
374 *
375 * @return Variable's value as array of long integers
376 */
377 public long[] getAsUInt32Array()
378 {
379 if ((variableType != TYPE_BINARY) || (binaryValue == null))
380 return null;
381
382 int count = binaryValue.length / 4;
383 long[] value = new long[count];
384 NXCPDataInputStream in = new NXCPDataInputStream(binaryValue);
385 try
386 {
387 for(int i = 0; i < count; i++)
388 value[i] = in.readUnsignedInt();
389 }
390 catch(IOException e)
391 {
392 }
393 return value;
394 }
395
396 /**
397 * Get variable's value as array of long integers. Variable should be of
398 * binary type, and integer values should be packet as DWORD's in network byte order.
399 *
400 * @return Variable's value as array of long integers
401 */
402 public Long[] getAsUInt32ArrayEx()
403 {
404 if ((variableType != TYPE_BINARY) || (binaryValue == null))
405 return null;
406
407 int count = binaryValue.length / 4;
408 Long[] value = new Long[count];
409 NXCPDataInputStream in = new NXCPDataInputStream(binaryValue);
410 try
411 {
412 for(int i = 0; i < count; i++)
413 value[i] = in.readUnsignedInt();
414 }
415 catch(IOException e)
416 {
417 }
418 return value;
419 }
420
421 /**
422 * @return the variableId
423 */
424 public long getVariableId()
425 {
426 return variableId;
427 }
428
429 /**
430 * @param variableId the variableId to set
431 */
432 public void setVariableId(final long variableId)
433 {
434 this.variableId = variableId;
435 }
436
437 /**
438 * @return the variableType
439 */
440 public int getVariableType()
441 {
442 return variableType;
443 }
444
445
446 /**
447 * Create NXCP DF structure
448 *
449 * @return
450 */
451 private int calculateBinarySize()
452 {
453 final int size;
454
455 switch(variableType)
456 {
457 case TYPE_INTEGER:
458 size = 12;
459 break;
460 case TYPE_INT64:
461 case TYPE_FLOAT:
462 size = 16;
463 break;
464 case TYPE_INT16:
465 size = 8;
466 break;
467 case TYPE_STRING:
468 size = stringValue.length() * 2 + 12;
469 break;
470 case TYPE_BINARY:
471 size = binaryValue.length + 12;
472 break;
473 default:
474 size = 8;
475 break;
476 }
477 return size;
478 }
479
480 public byte[] createNXCPDataField() throws IOException
481 {
482 final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(calculateBinarySize());
483 final DataOutputStream out = new DataOutputStream(byteStream);
484
485 out.writeInt(Long.valueOf(variableId).intValue());
486 out.writeByte(Long.valueOf(variableType).byteValue());
487 out.writeByte(0); // Padding
488 if (variableType == TYPE_INT16)
489 {
490 out.writeShort(integerValue.shortValue());
491 }
492 else
493 {
494 out.writeShort(0); // Padding
495 switch(variableType)
496 {
497 case TYPE_INTEGER:
498 out.writeInt(integerValue.intValue());
499 break;
500 case TYPE_INT64:
501 out.writeLong(integerValue);
502 break;
503 case TYPE_FLOAT:
504 out.writeDouble(realValue);
505 break;
506 case TYPE_STRING:
507 out.writeInt(stringValue.length() * 2);
508 out.writeChars(stringValue);
509 break;
510 case TYPE_BINARY:
511 out.writeInt(binaryValue.length);
512 out.write(binaryValue);
513 break;
514 }
515 }
516
517 // Align to 8-bytes boundary
518 final int rem = byteStream.size() % 8;
519 if (rem != 0)
520 {
521 out.write(new byte[8 - rem]);
522 }
523
524 return byteStream.toByteArray();
525 }
526 }