001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2017-2018. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.networktables;
009
010import java.util.Objects;
011
012/**
013 * A network table entry value.
014 */
015public final class NetworkTableValue {
016  NetworkTableValue(NetworkTableType type, Object value, long time) {
017    m_type = type;
018    m_value = value;
019    m_time = time;
020  }
021
022  NetworkTableValue(NetworkTableType type, Object value) {
023    this(type, value, NetworkTablesJNI.now());
024  }
025
026  NetworkTableValue(int type, Object value, long time) {
027    this(NetworkTableType.getFromInt(type), value, time);
028  }
029
030  /**
031   * Get the data type.
032   * @return The type.
033   */
034  public NetworkTableType getType() {
035    return m_type;
036  }
037
038  /**
039   * Get the data value stored.
040   * @return The type.
041   */
042  public Object getValue() {
043    return m_value;
044  }
045
046  /**
047   * Get the creation time of the value.
048   * @return The time, in the units returned by NetworkTablesJNI.now().
049   */
050  public long getTime() {
051    return m_time;
052  }
053
054  /*
055   * Type Checkers
056   */
057
058  /**
059   * Determine if entry value contains a value or is unassigned.
060   * @return True if the entry value contains a value.
061   */
062  public boolean isValid() {
063    return m_type != NetworkTableType.kUnassigned;
064  }
065
066  /**
067   * Determine if entry value contains a boolean.
068   * @return True if the entry value is of boolean type.
069   */
070  public boolean isBoolean() {
071    return m_type == NetworkTableType.kBoolean;
072  }
073
074  /**
075   * Determine if entry value contains a double.
076   * @return True if the entry value is of double type.
077   */
078  public boolean isDouble() {
079    return m_type == NetworkTableType.kDouble;
080  }
081
082  /**
083   * Determine if entry value contains a string.
084   * @return True if the entry value is of string type.
085   */
086  public boolean isString() {
087    return m_type == NetworkTableType.kString;
088  }
089
090  /**
091   * Determine if entry value contains a raw.
092   * @return True if the entry value is of raw type.
093   */
094  public boolean isRaw() {
095    return m_type == NetworkTableType.kRaw;
096  }
097
098  /**
099   * Determine if entry value contains a rpc definition.
100   * @return True if the entry value is of rpc definition type.
101   */
102  public boolean isRpc() {
103    return m_type == NetworkTableType.kRpc;
104  }
105
106  /**
107   * Determine if entry value contains a boolean array.
108   * @return True if the entry value is of boolean array type.
109   */
110  public boolean isBooleanArray() {
111    return m_type == NetworkTableType.kBooleanArray;
112  }
113
114  /**
115   * Determine if entry value contains a double array.
116   * @return True if the entry value is of double array type.
117   */
118  public boolean isDoubleArray() {
119    return m_type == NetworkTableType.kDoubleArray;
120  }
121
122  /**
123   * Determine if entry value contains a string array.
124   * @return True if the entry value is of string array type.
125   */
126  public boolean isStringArray() {
127    return m_type == NetworkTableType.kStringArray;
128  }
129
130  /*
131   * Type-Safe Getters
132   */
133
134  /**
135   * Get the entry's boolean value.
136   * @throws ClassCastException if the entry value is not of boolean type.
137   * @return The boolean value.
138   */
139  public boolean getBoolean() {
140    if (m_type != NetworkTableType.kBoolean) {
141      throw new ClassCastException("cannot convert " + m_type + " to boolean");
142    }
143    return ((Boolean)m_value).booleanValue();
144  }
145
146  /**
147   * Get the entry's double value.
148   * @throws ClassCastException if the entry value is not of double type.
149   * @return The double value.
150   */
151  public double getDouble() {
152    if (m_type != NetworkTableType.kDouble) {
153      throw new ClassCastException("cannot convert " + m_type + " to double");
154    }
155    return ((Number)m_value).doubleValue();
156  }
157
158  /**
159   * Get the entry's string value.
160   * @throws ClassCastException if the entry value is not of string type.
161   * @return The string value.
162   */
163  public String getString() {
164    if (m_type != NetworkTableType.kString) {
165      throw new ClassCastException("cannot convert " + m_type + " to string");
166    }
167    return (String)m_value;
168  }
169
170  /**
171   * Get the entry's raw value.
172   * @throws ClassCastException if the entry value is not of raw type.
173   * @return The raw value.
174   */
175  public byte[] getRaw() {
176    if (m_type != NetworkTableType.kRaw) {
177      throw new ClassCastException("cannot convert " + m_type + " to raw");
178    }
179    return (byte[])m_value;
180  }
181
182  /**
183   * Get the entry's rpc definition value.
184   * @throws ClassCastException if the entry value is not of rpc definition type.
185   * @return The rpc definition value.
186   */
187  public byte[] getRpc() {
188    if (m_type != NetworkTableType.kRpc) {
189      throw new ClassCastException("cannot convert " + m_type + " to rpc");
190    }
191    return (byte[])m_value;
192  }
193
194  /**
195   * Get the entry's boolean array value.
196   * @throws ClassCastException if the entry value is not of boolean array type.
197   * @return The boolean array value.
198   */
199  public boolean[] getBooleanArray() {
200    if (m_type != NetworkTableType.kBooleanArray) {
201      throw new ClassCastException("cannot convert " + m_type + " to boolean array");
202    }
203    return (boolean[])m_value;
204  }
205
206  /**
207   * Get the entry's double array value.
208   * @throws ClassCastException if the entry value is not of double array type.
209   * @return The double array value.
210   */
211  public double[] getDoubleArray() {
212    if (m_type != NetworkTableType.kDoubleArray) {
213      throw new ClassCastException("cannot convert " + m_type + " to double array");
214    }
215    return (double[])m_value;
216  }
217
218  /**
219   * Get the entry's string array value.
220   * @throws ClassCastException if the entry value is not of string array type.
221   * @return The string array value.
222   */
223  public String[] getStringArray() {
224    if (m_type != NetworkTableType.kStringArray) {
225      throw new ClassCastException("cannot convert " + m_type + " to string array");
226    }
227    return (String[])m_value;
228  }
229
230  /*
231   * Factory functions.
232   */
233
234  /**
235   * Creates a boolean entry value.
236   * @param value the value
237   * @return The entry value
238   */
239  public static NetworkTableValue makeBoolean(boolean value) {
240    return new NetworkTableValue(NetworkTableType.kBoolean, new Boolean(value));
241  }
242
243  /**
244   * Creates a boolean entry value.
245   * @param value the value
246   * @param time the creation time to use (instead of the current time)
247   * @return The entry value
248   */
249  public static NetworkTableValue makeBoolean(boolean value, long time) {
250    return new NetworkTableValue(NetworkTableType.kBoolean, new Boolean(value), time);
251  }
252
253  /**
254   * Creates a double entry value.
255   * @param value the value
256   * @return The entry value
257   */
258  public static NetworkTableValue makeDouble(double value) {
259    return new NetworkTableValue(NetworkTableType.kDouble, new Double(value));
260  }
261
262  /**
263   * Creates a double entry value.
264   * @param value the value
265   * @param time the creation time to use (instead of the current time)
266   * @return The entry value
267   */
268  public static NetworkTableValue makeDouble(double value, long time) {
269    return new NetworkTableValue(NetworkTableType.kDouble, new Double(value), time);
270  }
271
272  /**
273   * Creates a string entry value.
274   * @param value the value
275   * @return The entry value
276   */
277  public static NetworkTableValue makeString(String value) {
278    return new NetworkTableValue(NetworkTableType.kString, value);
279  }
280
281  /**
282   * Creates a string entry value.
283   * @param value the value
284   * @param time the creation time to use (instead of the current time)
285   * @return The entry value
286   */
287  public static NetworkTableValue makeString(String value, long time) {
288    return new NetworkTableValue(NetworkTableType.kString, value, time);
289  }
290
291  /**
292   * Creates a raw entry value.
293   * @param value the value
294   * @return The entry value
295   */
296  public static NetworkTableValue makeRaw(byte[] value) {
297    return new NetworkTableValue(NetworkTableType.kRaw, value);
298  }
299
300  /**
301   * Creates a raw entry value.
302   * @param value the value
303   * @param time the creation time to use (instead of the current time)
304   * @return The entry value
305   */
306  public static NetworkTableValue makeRaw(byte[] value, long time) {
307    return new NetworkTableValue(NetworkTableType.kRaw, value, time);
308  }
309
310  /**
311   * Creates a rpc entry value.
312   * @param value the value
313   * @return The entry value
314   */
315  public static NetworkTableValue makeRpc(byte[] value) {
316    return new NetworkTableValue(NetworkTableType.kRpc, value);
317  }
318
319  /**
320   * Creates a rpc entry value.
321   * @param value the value
322   * @param time the creation time to use (instead of the current time)
323   * @return The entry value
324   */
325  public static NetworkTableValue makeRpc(byte[] value, long time) {
326    return new NetworkTableValue(NetworkTableType.kRpc, value, time);
327  }
328
329  /**
330   * Creates a boolean array entry value.
331   * @param value the value
332   * @return The entry value
333   */
334  public static NetworkTableValue makeBooleanArray(boolean[] value) {
335    return new NetworkTableValue(NetworkTableType.kBooleanArray, value);
336  }
337
338  /**
339   * Creates a boolean array entry value.
340   * @param value the value
341   * @param time the creation time to use (instead of the current time)
342   * @return The entry value
343   */
344  public static NetworkTableValue makeBooleanArray(boolean[] value, long time) {
345    return new NetworkTableValue(NetworkTableType.kBooleanArray, value, time);
346  }
347
348  /**
349   * Creates a boolean array entry value.
350   * @param value the value
351   * @return The entry value
352   */
353  public static NetworkTableValue makeBooleanArray(Boolean[] value) {
354    return new NetworkTableValue(NetworkTableType.kBooleanArray, toNative(value));
355  }
356
357  /**
358   * Creates a boolean array entry value.
359   * @param value the value
360   * @param time the creation time to use (instead of the current time)
361   * @return The entry value
362   */
363  public static NetworkTableValue makeBooleanArray(Boolean[] value, long time) {
364    return new NetworkTableValue(NetworkTableType.kBooleanArray, toNative(value), time);
365  }
366
367  /**
368   * Creates a double array entry value.
369   * @param value the value
370   * @return The entry value
371   */
372  public static NetworkTableValue makeDoubleArray(double[] value) {
373    return new NetworkTableValue(NetworkTableType.kDoubleArray, value);
374  }
375
376  /**
377   * Creates a double array entry value.
378   * @param value the value
379   * @param time the creation time to use (instead of the current time)
380   * @return The entry value
381   */
382  public static NetworkTableValue makeDoubleArray(double[] value, long time) {
383    return new NetworkTableValue(NetworkTableType.kDoubleArray, value, time);
384  }
385
386  /**
387   * Creates a double array entry value.
388   * @param value the value
389   * @return The entry value
390   */
391  public static NetworkTableValue makeDoubleArray(Number[] value) {
392    return new NetworkTableValue(NetworkTableType.kDoubleArray, toNative(value));
393  }
394
395  /**
396   * Creates a double array entry value.
397   * @param value the value
398   * @param time the creation time to use (instead of the current time)
399   * @return The entry value
400   */
401  public static NetworkTableValue makeDoubleArray(Number[] value, long time) {
402    return new NetworkTableValue(NetworkTableType.kDoubleArray, toNative(value), time);
403  }
404
405  /**
406   * Creates a string array entry value.
407   * @param value the value
408   * @return The entry value
409   */
410  public static NetworkTableValue makeStringArray(String[] value) {
411    return new NetworkTableValue(NetworkTableType.kStringArray, value);
412  }
413
414  /**
415   * Creates a string array entry value.
416   * @param value the value
417   * @param time the creation time to use (instead of the current time)
418   * @return The entry value
419   */
420  public static NetworkTableValue makeStringArray(String[] value, long time) {
421    return new NetworkTableValue(NetworkTableType.kStringArray, value, time);
422  }
423
424  @Override
425  public boolean equals(Object o) {
426    if (o == this) {
427      return true;
428    }
429    if (!(o instanceof NetworkTableValue)) {
430      return false;
431    }
432    NetworkTableValue other = (NetworkTableValue) o;
433    return m_type == other.m_type && m_value.equals(other.m_value);
434  }
435
436  @Override
437  public int hashCode() {
438    return Objects.hash(m_type, m_value);
439  }
440
441  static boolean[] toNative(Boolean[] arr) {
442    boolean[] out = new boolean[arr.length];
443    for (int i = 0; i < arr.length; i++)
444      out[i] = arr[i];
445    return out;
446  }
447
448  static double[] toNative(Number[] arr) {
449    double[] out = new double[arr.length];
450    for (int i = 0; i < arr.length; i++)
451      out[i] = arr[i].doubleValue();
452    return out;
453  }
454
455  static Boolean[] fromNative(boolean[] arr) {
456    Boolean[] out = new Boolean[arr.length];
457    for (int i = 0; i < arr.length; i++)
458      out[i] = arr[i];
459    return out;
460  }
461
462  static Double[] fromNative(double[] arr) {
463    Double[] out = new Double[arr.length];
464    for (int i = 0; i < arr.length; i++)
465      out[i] = arr[i];
466    return out;
467  }
468
469  private NetworkTableType m_type;
470  private Object m_value;
471  private long m_time;
472}