Package center.system.msg

Source Code of center.system.msg.TPTPMsg$MessageOutputStream

package center.system.msg;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import ru.vassaev.core.PrmInterface;
import ru.vassaev.core.exception.SysException;
import ru.vassaev.core.io.ByteMsg;
import ru.vassaev.core.io.CloseableOutputStream;
import ru.vassaev.core.types.StringList;
import ru.vassaev.core.util.Strings;

public class TPTPMsg extends ByteMsg {
  public static final byte SOH = 0x01;
  public static final byte STX = 0x02;
  public static final byte EOT = 0x04;
  public static final byte ENQ = 0x05;
  public static final byte ACK = 0x06;
  public static final byte CR =  0x0D;
  public static final byte NAK = 0x15;
 
  private static final byte ETX = 0x03;
  private static final byte FLD = 0x1C;
  private int len = 0;

  public static String charset = "ibm866";
 
  private final Map<String, byte[]> data = new HashMap<String, byte[]>();

  public int getType() {
    return type;
  }
  public void reset() {
    data.clear();
    type = 0;
    len = 0;
  }

  private byte type = ENQ;
  private byte[] header = new byte[48];

  public ArrayList<byte[]> getMsg() throws SysException {
    ArrayList<byte[]> r = new ArrayList<byte[]>();
    int lrc = 0;
    int i;
    byte b;
    byte[] add;
    byte[] val;
    r.add(new byte[] { type });
    if (type != STX && type != SOH)
      return r;
    add = new byte[header.length];
    for (i = 0; i < header.length; i++) {
      b = header[i];
      lrc ^= b;
      add[i] = b;
    }
    r.add(add);
    for (Map.Entry<String, byte[]> e : data.entrySet()) {
      val = e.getValue();
      add = new byte[2 + val.length];
      lrc ^= FLD;
      add[0] = FLD;
      try {
        b = e.getKey().getBytes(charset)[0];
      } catch (UnsupportedEncodingException e1) {
        throw new SysException(e1);
      }
      lrc ^= b;
      add[1] = b;
      for (i = 0; i < val.length; i++) {
        b = val[i];
        lrc ^= b;
        add[i + 2] = b;
      }
      r.add(add);
    }
    lrc ^= ETX;
    r.add(new byte[] { ETX, (byte) (0xff & lrc) });
    return r;
  }

  public int getLengthMsg() {
    if (type != STX && type != SOH)
      return 1;
    return (1 // STX || SOH
        + header.length // HEADER
        + (data.size() * 2) + len // (FLD + NAME + DATA) * N
        + 1 // ETX
    + 1); // LRC
  }

  public int getLengthFull() {
    return getLengthMsg();
  }

  private void setField0(String key, String val) throws SysException {
    byte[] dta = data.remove(key);
    if (dta != null)
      len = len - dta.length;
    if (val != null) {
      try {
        dta = val.getBytes(charset);
      } catch (UnsupportedEncodingException e) {
        throw new SysException(e);
      }
      data.put(key, dta);
      len += dta.length;
    }
  }

  private final PrmInterface prms = new Prm();

  public PrmInterface getPrmInterface() throws SysException {
    return prms;
  }

  public class Prm implements PrmInterface {

    private void setFieldHeader(String key, String val) throws SysException {
      byte[] r;
      try {
        r = val.getBytes(charset);
      } catch (UnsupportedEncodingException e) {
        throw new SysException(e);
      }
      if ("DeviceType".equals(key)) {
        header[0] = r[0];
        header[1] = r[1];
      } else if ("TransmissionNumber".equals(key)) {
        header[2] = r[0];
        header[3] = r[1];
      } else if ("TerminalID".equals(key)) {
        System.arraycopy(r, 0, header, 4, 16);
      } else if ("EmployeeID".equals(key)) {
        System.arraycopy(r, 0, header, 20, 6);
      } else if ("CurrentDate".equals(key)) {
        System.arraycopy(r, 0, header, 26, 6);
      } else if ("CurrentTime".equals(key)) {
        System.arraycopy(r, 0, header, 32, 6);
      } else if ("MessageType".equals(key)) {
        header[38] = r[0];
      } else if ("MessageSubType".equals(key)) {
        header[39] = r[0];
      } else if ("TransactionCode".equals(key)) {
        header[40] = r[0];
        header[41] = r[1];
      } else if ("ProcessingFlag1".equals(key)) {
        header[42] = r[0];
      } else if ("ProcessingFlag2".equals(key)) {
        header[43] = r[0];
      } else if ("ProcessingFlag3".equals(key)) {
        header[44] = r[0];
      } else if ("ResponseCode".equals(key)) {
        header[45] = r[0];
        header[46] = r[1];
        header[47] = r[1];
      }
    }

    private String getFieldHeader(String key) throws SysException {
      try {
        if ("DeviceType".equals(key)) {
          return new String(header, 0, 2, charset);
        } else if ("TransmissionNumber".equals(key)) {
          return new String(header, 2, 2, charset);
        } else if ("TerminalID".equals(key)) {
          return new String(header, 4, 16, charset);
        } else if ("EmployeeID".equals(key)) {
          return new String(header, 20, 6, charset);
        } else if ("CurrentDate".equals(key)) {
          return new String(header, 26, 6, charset);
        } else if ("CurrentTime".equals(key)) {
          return new String(header, 32, 6, charset);
        } else if ("MessageType".equals(key)) {
          return new String(header, 38, 1, charset);
        } else if ("MessageSubType".equals(key)) {
          return new String(header, 39, 1, charset);
        } else if ("TransactionCode".equals(key)) {
          return new String(header, 40, 2, charset);
        } else if ("ProcessingFlag1".equals(key)) {
          return new String(header, 42, 1, charset);
        } else if ("ProcessingFlag2".equals(key)) {
          return new String(header, 43, 1, charset);
        } else if ("ProcessingFlag3".equals(key)) {
          return new String(header, 44, 1, charset);
        } else if ("ResponseCode".equals(key)) {
          return new String(header, 45, 3, charset);
        }
        return null;
      } catch (UnsupportedEncodingException e) {
        throw new SysException(e);
      }
    }

    public void setField(String key, String val) throws SysException {
      if (key == null)
        return;
      if (key.length() > 1) {
        if ("type".equals(key)) {
          byte type = (byte) (0xff & Strings.parseIntegerNvl(val, STX));
          if (type == STX || type == SOH ||
              type == EOT || type == ACK || type == CR || type == NAK || type == ENQ)
            TPTPMsg.this.type = type;
          else
            throw new SysException("The type of message is incorrect");
        } else
          setFieldHeader(key, val);
        return;
      }
      setField0(key, val);
    }

    public String getField(String key) throws SysException {
      if (key == null)
        return null;
      if (key.length() > 1) {
        if ("type".equals(key)) {
          return String.valueOf(type);
        }
        return getFieldHeader(key);
      }
      byte[] dta = data.get(key);
      if (dta == null)
        return null;
      try {
        return new String(dta, charset);
      } catch (UnsupportedEncodingException e) {
        throw new SysException(e);
      }
    }

    public byte[] getByteField(String key) throws SysException {
      if (key == null)
        return null;
      if (key.length() > 1)
        try {
          if ("type".equals(key)) {
            return String.valueOf(type).getBytes(charset);
          }
          return getFieldHeader(key).getBytes(charset);
        } catch (UnsupportedEncodingException e) {
          throw new SysException(e);
        }
      return data.get(key);
    }

    public void clearField(String key) throws SysException {
      setField(key, null);
    }

    public boolean isPresentField(String key) throws SysException {
      if (key == null)
        return false;
      if (key.length() > 1) {
        if ("type".equals(key)) {
          return true;
        }
        return (getFieldHeader(key) != null);
      }
      return data.get(key) != null;
    }

    public void clearFields() throws SysException {
      len = 0;
      data.clear();
    }

    public StringList getFieldNames() {
      StringList sl = new StringList();
      sl.add("type");
      if (type == STX || type == SOH) {
        sl.add("DeviceType");
        sl.add("TransmissionNumber");
        sl.add("TerminalID");
        sl.add("EmployeeID");
        sl.add("CurrentDate");
        sl.add("CurrentTime");
        sl.add("MessageType");
        sl.add("MessageSubType");
        sl.add("TransactionCode");
        sl.add("ProcessingFlag1");
        sl.add("ProcessingFlag2");
        sl.add("ProcessingFlag3");
        sl.add("ResponseCode");
        sl.addAll(data.keySet());
      }
      return sl;
    }

  }

  public String getKey() throws SysException {
    return null;
  }

  public void setKey(String key) throws SysException {
  }

  public CloseableOutputStream getOutputStream() throws IOException {
    return new MessageOutputStream();
  }

  private class MessageOutputStream extends CloseableOutputStream {
    private int i = 0;
    private int pos = 0;
    private int ll = 0;
    private StringBuffer sb = new StringBuffer();
    private char fld;
    private int lrc = 0;

    public void write(int b) throws IOException {
      ll ++;
      if (b == -1 && i >= 0)
        throw new IOException("The stream isn't comleted (pos = " + ll + ")");
      if (i < 0) // Если поток закрыт
        throw new IOException("The stream is already closed");
      // System.out.println("WRITE:"+(char)b);
      switch (i) {
      case 0: { // Type
        type = (byte) (b & 0xff);
        if (type == EOT || type == ACK || type == CR || type == NAK || type == ENQ) {
          i = -1;
        } else if (type == STX || type == SOH) {
          i++;
          pos = 0;
        } else
          throw new IOException("The type of message is incorrect");
        break;
      }
      case 1: {// Header
        lrc ^= b;
        header[pos] = (byte) (b & 0xff);
        pos++;
        if (pos == header.length) {
          i++;
          pos = 0;
        }
        break;
      }
      case 2: {// Fields
        byte bt = (byte) (b & 0xff);
         
        lrc ^= b;
        if (pos == 0) {
          if (bt == ETX) {
            i++;
            break;
          }
          if (bt != FLD)
            throw new IOException("Incorrect fields' starting (" + i + ","
                + pos + ", pos = " + ll + ", byte = " + b + ")");
          pos++;
          break;
        } else if (pos == 1) {
          if (bt == FLD)
            throw new IOException("Incorrect field's starting (" + i + ","
                + pos + ") (pos = " + ll + ")");
          fld = (char) bt;
          pos++;
          break;
        }
        try {
          if (bt == FLD) {
            setField0(Character.toString(fld), sb.toString());
            sb.setLength(0);
            pos = 1;
          } else if (bt == ETX) {
            setField0(Character.toString(fld), sb.toString());
            i++;
            pos = 0;
          } else
            sb.append((char) bt);
        } catch (SysException e) {
          throw new IOException(e);
        }
        break;
      }
      case 3: {//LRC
        if ((0xff & lrc) != (0xff & b))
          throw new IOException("Incorrect LRC (pos = " + ll + ")");
        i = -1;
      }
      }
    }

    public void close() throws IOException {
      i = -1;
      pos = -1;
    }

    public boolean isClosed() {
      return (i == -1);
    }
  }
}
TOP

Related Classes of center.system.msg.TPTPMsg$MessageOutputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.