package art.servers.etdserver.protocols.diamond.file; import art.library.utils.common.TimeUtils; import java.io.*; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.*; public final class DIAMOND_File { public DIAMOND_Header header; public DIAMOND_BinnedSetup binnedSetup; public DIAMOND_SerialNumber serialNumber; public DIAMOND_RecordInterval recordInterval; public DIAMOND_EndOfFile endOfFile; // One per lane public List llaneConfiguration = new ArrayList(); // Tables public int[] minAxleBinTable; public int[] maxAxleBinTable; public int[] minSpeedBinTable; public int[] maxSpeedBinTable; public int[] minLengthBinTable; public int[] maxLengthBinTable; // Raw data public Vector raw = new Vector(); // One per period // Todos deberían ser de la misma longitud (excepto si no es de longitud cero) public List ltimestamps = new ArrayList(); public List lbinnedAxle = new ArrayList(); public List lbinnedLength = new ArrayList(); public List lbinnedSpeed = new ArrayList(); public List lbinnedSpeedxLenght = new ArrayList(); public List lbinnedSpeedxAxle = new ArrayList(); public List lbinnedError = new ArrayList(); public List lcount = new ArrayList(); // Funciones public DIAMOND_File () { } public DIAMOND_File (int[] receive) { retrieveFile(receive); } private void retrieveFile (int[] receive) { try { int apuntador = 0; while(true) { int flag = receive[apuntador]; if (flag < 0) flag += 256; switch (flag) { case 0x01 : header(this, receive, apuntador); apuntador += 80; break; case 0x02 : binnedDataSetup(this, receive, apuntador); apuntador += 66; break; case 0x03 : counterSerialNumber(this, receive, apuntador); apuntador += 32; break; case 0x10 : case 0x20 : case 0x30 : case 0x40 : case 0x50 : case 0x60 : case 0x70 : case 0x80 : laneConfiguration(this, receive, apuntador, flag); apuntador += 25; break; case 0x11 : case 0x21 : case 0x31 : case 0x41 : case 0x51 : case 0x61 : case 0x71 : case 0x81 : apuntador += 7; break; case 0x12 : case 0x22 : case 0x32 : case 0x42 : case 0x52 : case 0x62 : case 0x72 : case 0x82 : apuntador += 9; break; case 0x13 : case 0x23 : case 0x33 : case 0x43 : case 0x53 : case 0x63 : case 0x73 : case 0x83 : apuntador += 12; break; case 0x14 : case 0x24 : case 0x34 : case 0x44 : case 0x54 : case 0x64 : case 0x74 : case 0x84 : apuntador += 14; break; case 0x90 : countData(this, receive, apuntador+1); apuntador += (1 + (2 * this.header.activelanes)); break; case 0x91 : binnedAxleData(this, receive, apuntador+1); apuntador += (1 + (2 * (this.header.activelanes * this.binnedSetup.numberaxle))); break; case 0x92 : binnedSpeedData(this, receive, apuntador+1); apuntador += (1 + (2 * (this.header.activelanes * this.binnedSetup.numberspeed))); break; case 0x93 : binnedLengthData(this, receive, apuntador+1); apuntador += (1 + (2 * (this.header.activelanes * this.binnedSetup.numberlength))); break; case 0x94 : apuntador += (1 + 2 * (this.header.activelanes + this.binnedSetup.numbergap)); break; case 0x95 : apuntador += (1 + 2 * (this.header.activelanes + this.binnedSetup.numberheadway)); break; case 0x96 : apuntador = binnedSpeedxLengthData(this, receive, apuntador+1); break; case 0x97 : apuntador = binnedSpeedxAxleData(this, receive, apuntador+1); break; case 0x9F : errorBininfo(this, receive, apuntador+1); apuntador += (1 + 8 * (this.header.activelanes)); break; case 0xF0 : apuntador += 6; break; case 0xF1 : recordInterval(this, receive, apuntador+1); apuntador += 3; break; case 0xFF : enfOfFile(this, receive, apuntador); apuntador += 6; return; case 0x2F : // System.out.println("No implemented yet : flag " + flag + ", byte " + apuntador); apuntador += 5; break; case 0x4F : // System.out.println("No implemented yet : flag " + flag + ", byte " + apuntador); apuntador += 5; break; case 0x5F : // System.out.println("No implemented yet : flag " + flag + ", byte " + apuntador); apuntador += 5; break; case 0x6F : // System.out.println("No implemented yet : flag " + flag + ", byte " + apuntador); apuntador += 5; break; case 0x7F : // System.out.println("No implemented yet : flag " + flag + ", byte " + apuntador); apuntador += 5; break; case 0x8F : // System.out.println("No implemented yet : flag " + flag + ", byte " + apuntador); apuntador += 5; break; // Apollo raw format case 0x1A : apuntador = rawData(0, receive, apuntador); header.activelanes = Math.max(header.activelanes, 1); break; case 0x3A : apuntador = rawData(1, receive, apuntador); header.activelanes = Math.max(header.activelanes, 2); break; case 0x1F : apuntador = rawDataError(0, receive, apuntador); header.activelanes = Math.max(header.activelanes, 1); break; case 0x3F : apuntador = rawDataError(1, receive, apuntador); header.activelanes = Math.max(header.activelanes, 2); break; default : // System.out.println("No implemented yet : flag " + Integer.toHexString(flag).toUpperCase() + ", byte " + apuntador); return; } } } catch (Exception e) { } if (ltimestamps.size() == 0) { // EndOfFile Flag not received // ltimestamps calculation with header and recordInterval flags information DIAMOND_Header h = header; int periodoMs = recordInterval.minutes * 60 * 1000; Calendar calendarStart = Calendar.getInstance(); calendarStart.set(Calendar.DATE, h.startday); calendarStart.set(Calendar.MONTH, h.startmonth - 1); calendarStart.set(Calendar.YEAR, h.startyear + 2000); calendarStart.set(Calendar.HOUR_OF_DAY, h.starthour); calendarStart.set(Calendar.MINUTE, h.startminute); calendarStart.set(Calendar.SECOND, 0); calendarStart.set(Calendar.MILLISECOND, 0); Calendar calendarStop = Calendar.getInstance(); calendarStop.set(Calendar.DATE, h.stopday); calendarStop.set(Calendar.MONTH, h.stopmonth - 1); calendarStop.set(Calendar.YEAR, h.stopyear + 2000); calendarStop.set(Calendar.HOUR_OF_DAY, h.stophour); calendarStop.set(Calendar.MINUTE, h.stopminute); calendarStop.set(Calendar.SECOND, 0); calendarStop.set(Calendar.MILLISECOND, 0); while (calendarStart.before(calendarStop)) { long ts = new Long(calendarStart.getTimeInMillis()); ts = TimeUtils.thisperiod(recordInterval.minutes*60, ts); ltimestamps.add(ts); calendarStart.setTimeInMillis(calendarStart.getTimeInMillis() + periodoMs); } } } private void header(DIAMOND_File file, int[] receive, int apuntador) { byte in[] = new byte[80]; for (int i=0; i<80; i++) in[i] = (byte)receive[apuntador+i]; DIAMOND_Header header = new DIAMOND_Header(); header.site = S(in, 1, 10); header.lanedirection = S(in, 11, 15); header.location = S(in, 26, 15); header.startyear = DIAMOND_SubCharSet((byte)in[41],7,7); header.startmonth = DIAMOND_SubWordSet(in[41],in[42],8,4); header.startday = DIAMOND_SubCharSet(in[42],4,5); header.starthour = DIAMOND_SubCharSet(in[43],4,5); header.startminute = DIAMOND_SubCharSet(in[44],5,6); header.stopyear = DIAMOND_SubCharSet(in[45],7,7); header.stopmonth = DIAMOND_SubWordSet(in[45],in[46],8,4); header.stopday = DIAMOND_SubCharSet(in[46],4,5); header.stophour = DIAMOND_SubCharSet(in[47],4,5); header.stopminute = DIAMOND_SubCharSet(in[48],5,6); header.storagemode = DIAMOND_SubCharSet(in[49],7,3); header.dateformat = DIAMOND_SubCharSet(in[49],4,2); header.numberformat = DIAMOND_SubCharSet(in[49],2,2); header.activelanes = DIAMOND_SubCharSet(in[50],7,8); header.unittype = DIAMOND_SubCharSet(in[51],7,8); header.unitversion = DIAMOND_Word(in[52],in[53]); header.retrieved = true; header.start = F(header.startday,2)+"/"+F(header.stopmonth,2)+"/"+F(header.stopyear,2)+" "; header.stop = F(header.stopday,2)+"/"+F(header.stopmonth,2)+"/"+F(header.stopyear,2)+" "; file.header = header; } private void binnedDataSetup(DIAMOND_File file, int[] receive, int apuntador) { byte in[] = new byte[66]; for (int i=0; i<66; i++) in[i] = (byte)receive[apuntador+i]; DIAMOND_BinnedSetup binnedSetup = new DIAMOND_BinnedSetup(); file.binnedSetup = binnedSetup; binnedSetup.numberspeed = in[1]; binnedSetup.numberaxle = in[14]; binnedSetup.numberlength = in[27]; binnedSetup.numbergap = in[40]; binnedSetup.numberheadway = in[53]; binnedSetup.namespeed = S(in, 2, 12); binnedSetup.nameaxle = S(in, 15, 12); binnedSetup.namelength = S(in, 28, 12); binnedSetup.namegap = S(in, 41, 12); binnedSetup.nameheadway = S(in, 54, 12); binnedSetup.retrieved = true; file.minAxleBinTable = new int[binnedSetup.numberaxle]; file.minSpeedBinTable = new int[binnedSetup.numberspeed]; file.minLengthBinTable = new int[binnedSetup.numberlength]; file.maxAxleBinTable = new int[binnedSetup.numberaxle]; file.maxSpeedBinTable = new int[binnedSetup.numberspeed]; file.maxLengthBinTable = new int[binnedSetup.numberlength]; } private void counterSerialNumber(DIAMOND_File file, int[] receive, int apuntador) { byte in[] = new byte[32]; for (int i=0; i<32; i++) in[i] = (byte)receive[apuntador+i]; DIAMOND_SerialNumber serialNumber = new DIAMOND_SerialNumber(); serialNumber.serialnumber = S(in, 1, 31); serialNumber.retrieved = true; file.serialNumber = serialNumber; } private void laneConfiguration(DIAMOND_File file, int[] receive, int apuntador, int flag) { byte in[] = new byte[25]; for (int i=0; i<25; i++) in[i] = (byte)receive[apuntador+i]; // Si existe el flag es que es un carril direccional, sumar 0x80 al flag for (int i=0; i 0) && (file.lbinnedAxle.size() != file.ltimestamps.size())) { return; } if ((file.lbinnedSpeed.size() > 0) && (file.lbinnedSpeed.size() != file.ltimestamps.size())) { return; } if ((file.lbinnedLength.size() > 0) && (file.lbinnedLength.size() != file.ltimestamps.size())) { return; } if ((file.lbinnedError.size() > 0) && (file.lbinnedError.size() != file.ltimestamps.size())) { return; } if ((file.lcount.size() > 0) && (file.lcount.size() != file.ltimestamps.size())) { return; } } //////////////////////////////////////////////////////////////////////////////////// private int V (byte[] trama) { return (Integer.parseInt(new String(trama), 16)); } private int V (int[] trama, int apuntador, int longitud) { byte[] aux = new byte[longitud]; for (int i=apuntador; i<(apuntador+longitud); i++) aux[i-apuntador] = (byte)trama[i]; return (Integer.parseInt(new String(aux), 16)); } private String S (int[] trama, int apuntador, int longitud) { byte[] cadena = new byte[longitud]; for (int i=apuntador; i<(apuntador+longitud); i++) cadena[i-apuntador] = (byte)trama[i]; return ((new String(cadena)).trim()); } private String S (byte[] trama, int apuntador, int longitud) { byte[] cadena = new byte[longitud]; for (int i=apuntador; i<(apuntador+longitud); i++) cadena[i-apuntador] = (byte)trama[i]; return ((new String(cadena)).trim()); } private int DIAMOND_SubCharSet(byte in, int bit, int length) { int out = 0; for (int i=bit-length+1; i<=bit; i++) out += 0x01<>(bit-length+1)); return(out); } private int DIAMOND_SubWordSet(byte high, byte low, int bit, int length) { int out = 0; int h = (int)high; int l = (int)low; if (h<0) h += 256; if (l<0) l += 256; int in =(int)(((h)<<8) + l); for (int i=bit-length+1; i<=bit; i++) out += 0x01<>(bit-length+1)); return(out); } private int DIAMOND_Word (byte low, byte high) { int h = (int)high; int l = (int)low; if (h<0) h += 256; if (l<0) l += 256; int valor = (int)((h<<8) + l); return (valor); } private String F(int numero, int longitud) { String s = ""+numero; for (int i=0; i<(longitud-s.length()); i++) s = "0" + s; return s; } private String FS(int numero, int longitud) { String s = ""+numero; for (int i=0; i<(longitud-s.length()); i++) s = " " + s; return s; } private String IntToString(int valor, int digitos) { try { String res = ""; if (valor < 1000) res = res + "0"; if (valor < 100) res = res + "0"; if (valor < 10) res = res + "0"; res = res + valor; return res; } catch (Exception e) { } return "" + valor; } }