/*******************************************************************************
* Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University
* as Operator of the SLAC National Accelerator Laboratory.
* Copyright (c) 2011 Brookhaven National Laboratory.
* EPICS archiver appliance is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*******************************************************************************/
package org.epics.archiverappliance.config;
import java.util.HashMap;
import java.util.LinkedList;
import org.epics.archiverappliance.data.SampleValue;
import org.epics.archiverappliance.data.ScalarStringSampleValue;
import org.epics.archiverappliance.data.ScalarValue;
import org.epics.archiverappliance.data.VectorStringSampleValue;
import org.epics.archiverappliance.data.VectorValue;
import org.json.simple.JSONArray;
import org.json.simple.JSONValue;
import edu.stanford.slac.archiverappliance.PB.EPICSEvent.PayloadType;
/**
* The various DBR types supported by the EPICS appliance archiver.
* We can either follow the names as they are defined in db_access.h (which makes int's a 16 bit java short) or we can follow JCA's names which makes this closer to Java.
* For now, we follow JCA to minimize confusion for Java developers.
* @author mshankar
*
*/
public enum ArchDBRTypes {
DBR_SCALAR_STRING(0, false, "String", PayloadType.SCALAR_STRING, true),
DBR_SCALAR_SHORT(1, false, "short", PayloadType.SCALAR_SHORT, true),
DBR_SCALAR_FLOAT(2, false, "float", PayloadType.SCALAR_FLOAT, true),
DBR_SCALAR_ENUM(3, false, "enum", PayloadType.SCALAR_ENUM, true),
DBR_SCALAR_BYTE(4, false, "byte", PayloadType.SCALAR_BYTE, true),
DBR_SCALAR_INT(5, false, "int", PayloadType.SCALAR_INT, true),
DBR_SCALAR_DOUBLE(6, false, "double", PayloadType.SCALAR_DOUBLE, true),
DBR_WAVEFORM_STRING(7, true, "String", PayloadType.WAVEFORM_STRING, true),
DBR_WAVEFORM_SHORT(8, true, "short", PayloadType.WAVEFORM_SHORT, true),
DBR_WAVEFORM_FLOAT(9, true, "float", PayloadType.WAVEFORM_FLOAT, true),
DBR_WAVEFORM_ENUM(10, true, "enum", PayloadType.WAVEFORM_ENUM, true),
DBR_WAVEFORM_BYTE(11, true, "byte", PayloadType.WAVEFORM_BYTE, true),
DBR_WAVEFORM_INT(12, true, "int", PayloadType.WAVEFORM_INT, true),
DBR_WAVEFORM_DOUBLE(13, true, "double", PayloadType.WAVEFORM_DOUBLE, true),
DBR_V4_GENERIC_BYTES(14, true, "v4generic", PayloadType.V4_GENERIC_BYTES, false);
private static HashMap<PayloadType, ArchDBRTypes> PBTypeReverseMapping = new HashMap<PayloadType, ArchDBRTypes>();
static {
// Compute reverse lookups;
for(ArchDBRTypes type : ArchDBRTypes.values()) {
PBTypeReverseMapping.put(type.getPBPayloadType(), type);
}
}
private int integerMap;
private String primitiveName;
private boolean isWaveForm = false;
private PayloadType PBPayloadType;
private boolean isV3Type = true;
/**
* The integerMap is the value from db_access.h.
* We get the archiver specific JCA type from the JCA javadoc.
* JCA subsumes both scalars and vectors into a single type system; we separate them for space reasons.
* @param fromdbaccess_h
* @param isWaveform
* @param primitivename
* @param payloadType
* @param isV3Type
*/
private ArchDBRTypes(int fromdbaccess_h, boolean isWaveform, String primitivename, PayloadType payloadType, boolean isV3Type) {
this.integerMap = fromdbaccess_h;
this.primitiveName = primitivename;
this.isWaveForm = isWaveform;
this.PBPayloadType = payloadType;
this.isV3Type = isV3Type;
}
public String getPrimitiveName() {
return primitiveName;
}
/**
* Get a integer assigned to this type as defined in db_access.h
* @return integerMap
*/
public int getIntegerMap() {
return integerMap;
}
/**
* Is this thing a vector (or in EPICS terms, a waveform).
* @return isWaveForm True if a waveform
*/
public boolean isWaveForm() {
return isWaveForm;
}
/**
* This is used to reverse map from the PB Payloadtype enum into a DBR type
* @param payloadtype PayloadType
* @return ArchDBRTypes
*/
public static ArchDBRTypes valueOf(PayloadType payloadtype) {
return PBTypeReverseMapping.get(payloadtype);
}
public PayloadType getPBPayloadType() {
return PBPayloadType;
}
public boolean isV3Type() {
return isV3Type;
}
public static SampleValue sampleValueFromString(ArchDBRTypes dbrType, String sampleValueStr) {
switch(dbrType) {
case DBR_SCALAR_STRING: {
return new ScalarStringSampleValue(sampleValueStr);
}
case DBR_SCALAR_SHORT: {
return new ScalarValue<Short>(Short.parseShort(sampleValueStr));
}
case DBR_SCALAR_FLOAT: {
return new ScalarValue<Float>(Float.parseFloat(sampleValueStr));
}
case DBR_SCALAR_ENUM: {
return new ScalarValue<Short>(Short.parseShort(sampleValueStr));
}
case DBR_SCALAR_BYTE: {
return new ScalarValue<Byte>(Byte.parseByte(sampleValueStr));
}
case DBR_SCALAR_INT: {
return new ScalarValue<Integer>(Integer.parseInt(sampleValueStr));
}
case DBR_SCALAR_DOUBLE: {
return new ScalarValue<Double>(Double.parseDouble(sampleValueStr));
}
case DBR_WAVEFORM_STRING: {
LinkedList<String> buf = new LinkedList<String>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add((String) val);
}
}
return new VectorStringSampleValue(buf);
}
case DBR_WAVEFORM_SHORT: {
LinkedList<Short> buf = new LinkedList<Short>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add(Short.parseShort((String) val));
}
}
return new VectorValue<Short>(buf);
}
case DBR_WAVEFORM_FLOAT: {
LinkedList<Float> buf = new LinkedList<Float>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add(Float.parseFloat((String) val));
}
}
return new VectorValue<Float>(buf);
}
case DBR_WAVEFORM_ENUM: {
LinkedList<Short> buf = new LinkedList<Short>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add(Short.parseShort((String) val));
}
}
return new VectorValue<Short>(buf);
}
case DBR_WAVEFORM_BYTE: {
LinkedList<Byte> buf = new LinkedList<Byte>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add(Byte.parseByte((String) val));
}
}
return new VectorValue<Byte>(buf);
}
case DBR_WAVEFORM_INT: {
LinkedList<Integer> buf = new LinkedList<Integer>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add(Integer.parseInt((String) val));
}
}
return new VectorValue<Integer>(buf);
}
case DBR_WAVEFORM_DOUBLE: {
LinkedList<Double> buf = new LinkedList<Double>();
JSONArray vals = (JSONArray) JSONValue.parse(sampleValueStr);
if(vals != null && !vals.isEmpty()) {
for(Object val : vals) {
buf.add(Double.parseDouble((String) val));
}
}
return new VectorValue<Double>(buf);
}
case DBR_V4_GENERIC_BYTES: {
throw new UnsupportedOperationException("We do not support this for V4 types yet.");
}
default:
throw new UnsupportedOperationException("When we add a new DBR_TYPE, we should add some code here.");
}
}
}