//: TLink.java
package de.desy.tine.headers;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import de.desy.tine.addrUtils.TSrvEntry;
import de.desy.tine.client.TLink;
import de.desy.tine.dataUtils.TDataType;
import de.desy.tine.definitions.TAccess;
import de.desy.tine.definitions.TErrorList;
import de.desy.tine.definitions.TFormat;
import de.desy.tine.endianUtils.Swap;
import de.desy.tine.server.logger.MsgLog;
import de.desy.tine.types.SPECTRUM;
public final class TContractP5
{
public String eqmProperty; // 32 char
public String eqmDeviceName; // 16 char
public String eqmName; // 8 char
public int dataSizeIn;
public int dataSizeOut;
public byte hEqmName; // as yet un-used
public byte dataAccess;
public byte dataFormatIn;
public byte dataFormatOut;
public String dataTagIn; // 8 char
public String dataTagOut; // 8 char
// non 'network' fields :
static public final int hdrSizeInBytes = (32+16+8+2*4+4*1+2*8);
int totalSizeInBytes;
public ByteArrayOutputStream dBuffer;
public boolean equals(TContractP5 contract)
{
if (contract.eqmProperty.compareTo(eqmProperty) != 0) return false;
if (contract.eqmDeviceName.compareTo(eqmDeviceName) != 0) return false;
if (contract.eqmName.compareTo(eqmName) != 0) return false;
if (contract.dataSizeIn != dataSizeIn) return false;
if (contract.dataSizeOut != dataSizeOut) return false;
if (TAccess.toBase(contract.dataAccess) != TAccess.toBase(dataAccess)) return false;
if (contract.dataFormatIn != dataFormatIn) return false;
if (contract.dataFormatOut != dataFormatOut) return false;
if (contract.dataTagIn.compareTo(dataTagIn) != 0) return false;
if (contract.dataTagOut.compareTo(dataTagOut) != 0) return false;
return true;
}
// local constructor for local histories, alarm watches, etc....
public TContractP5(String property,String device,String eqm,TDataType dout,TDataType din,short access)
{
eqmProperty = property;
eqmDeviceName = device;
eqmName = eqm;
if (din != null)
{
dataSizeIn = din.dArrayLength;
dataFormatIn = (byte)din.dFormat;
dataTagIn = din.getTag();
}
else
{
dataSizeIn = 0;
dataFormatIn = (byte)TFormat.CF_NULL;
dataTagIn = "";
}
if (dout != null)
{
dataSizeOut = dout.dArrayLength;
dataFormatOut = (byte)dout.dFormat;
dataTagOut = dout.getTag();
}
else
{
dataSizeOut = 0;
dataFormatOut = (byte)TFormat.CF_NULL;
dataTagOut = "";
}
dataAccess = (byte)access;
}
public TContractP5(TLink lnk) // going out (client constructor)
{
int i;
// get 6-character module name
TSrvEntry mod;
mod = new TSrvEntry(lnk);
if (mod.fecAddr == null) return;
if (lnk.srvAddr != null)
{
lnk.srvAddr.fecAddr = mod.fecAddr;
lnk.srvAddr.eqmName = mod.eqmName;
// fill in the local fields ...
eqmName = mod.eqmName;
eqmProperty = lnk.devProperty;
eqmDeviceName = lnk.devName;
dataSizeOut = lnk.dOutput.getArrayLength();
dataSizeIn = lnk.dInput.getArrayLength();
dataFormatOut = (byte)lnk.dOutput.getFormat();
dataFormatIn = (byte)lnk.dInput.getFormat();
dataAccess = (byte)lnk.devAccess;
dataTagOut = lnk.dOutput.getTag();
dataTagIn = lnk.dInput.getTag();
}
try
{
dBuffer = new ByteArrayOutputStream(hdrSizeInBytes);
DataOutputStream ds = new DataOutputStream(dBuffer);
byte[] bstr = new byte[32];
byte[] tmp = lnk.devProperty.getBytes();
byte[] tmp2 = lnk.devName.getBytes();
if (tmp2.length > 16 && tmp.length < 16) // the Channel Access Long device names trick ...
{
for (i=0; i<16; i++) bstr[i] = i < tmp.length ? tmp[i] : 0; bstr[16] = 0;
for (i=0; i<15; i++) bstr[i+17] = i < tmp2.length - 15 ? tmp2[i+15] : 0;
byte[] amp = "&".getBytes();
tmp2[15] = amp[0];
}
else
{
for (i=0; i<32; i++) bstr[i] = i < tmp.length ? tmp[i] : 0;
}
ds.write(bstr,0,32);
for (i=0; i<16; i++) bstr[i] = i < tmp2.length ? tmp2[i] : 0;
ds.write(bstr,0,16);
tmp = mod.eqmName.getBytes();
for (i=0; i<8; i++) bstr[i] = i < tmp.length ? tmp[i] : 0;
ds.write(bstr,0,8);
int inlen = lnk.dInput.getArrayLength();
int outlen = lnk.dOutput.getArrayLength();
if (lnk.dOutput.getFormat() == TFormat.CF_STRUCT) outlen = lnk.dOutput.getSizeInBytes();
if (lnk.dInput.getFormat() == TFormat.CF_STRUCT) inlen = lnk.dInput.getSizeInBytes();
ds.writeInt(Swap.Long(inlen));
ds.writeInt(Swap.Long(outlen));
ds.writeByte(0);
ds.writeByte(lnk.devAccess);
ds.writeByte((byte)lnk.dInput.getFormat());
ds.writeByte((byte)lnk.dOutput.getFormat());
tmp = lnk.dInput.getTag().getBytes();
for (i=0; i<8; i++) bstr[i] = i < tmp.length ? tmp[i] : 0;
ds.write(bstr,0,8);
tmp = lnk.dOutput.getTag().getBytes();
for (i=0; i<8; i++) bstr[i] = i < tmp.length ? tmp[i] : 0;
ds.write(bstr,0,8);
totalSizeInBytes = hdrSizeInBytes + lnk.dInput.getSizeInBytes();
ds.close();
}
catch (IOException e)
{
e.printStackTrace();
MsgLog.log("TContractP5",e.toString(),TErrorList.code_failure,e,0);
}
}
private void prepareInComing(DataInputStream ds)
{
byte[] d = new byte[32];
try
{
ds.read(d,0,32);
eqmProperty = new String(d,0,32).trim();
ds.read(d,0,16);
eqmDeviceName = new String(d,0,16).trim();
ds.read(d,0,8);
eqmName = new String(d,0,8).trim();
dataSizeIn = Swap.Long(ds.readInt());
dataSizeOut = Swap.Long(ds.readInt());
hEqmName = ds.readByte();
dataAccess = ds.readByte();
dataFormatIn = ds.readByte();
dataFormatOut = ds.readByte();
ds.read(d,0,8);
dataTagIn = new String(d,0,8).trim();
ds.read(d,0,8);
dataTagOut = new String(d,0,8).trim();
}
catch (IOException e)
{
e.printStackTrace();
MsgLog.log("TContractP5.prepareIncoming",e.toString(),TErrorList.code_failure,e,0);
}
}
public TContractP5(byte[] data, int off, int len)
{
try
{
ByteArrayInputStream is = new ByteArrayInputStream(data,off,len);
DataInputStream ds = new DataInputStream(is);
prepareInComing(ds);
ds.close();
is.close();
}
catch (IOException e)
{
e.printStackTrace();
MsgLog.log("TContractP5",e.toString(),TErrorList.code_failure,e,0);
}
}
public TContractP5(DataInputStream ds) // coming in (server constructor)
{
prepareInComing(ds);
}
public TContractP5(ByteArrayInputStream inBuffer) // coming in (server constructor)
{
DataInputStream ds = new DataInputStream(inBuffer);
prepareInComing(ds);
try
{
ds.close();
}
catch (IOException e)
{
e.printStackTrace();
MsgLog.log("TContractP5",e.toString(),TErrorList.code_failure,e,0);
}
}
public int getOutputDataSize()
{
int fmtsiz = 0;
if ((fmtsiz=TFormat.formatSizeOf(dataFormatOut)) > 0)
{
int datasize = fmtsiz * dataSizeOut;
if (dataFormatOut == TFormat.CF_SPECTRUM) datasize += SPECTRUM.hdrSizeInBytes;
return datasize;
}
return 0;
}
public String toString()
{
String msg = new String("target : <"+eqmName+">/"+eqmDeviceName+"["+eqmProperty+"]");
msg = msg.concat("" + TAccess.toString(dataAccess) + " access");
msg = msg.concat("\ninput : " + dataSizeIn + " " + TFormat.toString(dataFormatIn) + " value(s)");
if (dataTagIn.length() > 0) msg = msg.concat(" tag = " + dataTagIn);
msg = msg.concat("\noutput : " + dataSizeOut + " " + TFormat.toString(dataFormatOut) + " value(s)");
if (dataTagOut.length() > 0) msg = msg.concat(" tag = " + dataTagOut);
return msg;
}
public byte[] toByteArray() { return dBuffer != null ? dBuffer.toByteArray() : null; }
}