Package center.system.msg

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

package center.system.msg;

import ru.vassaev.core.exception.SysException;

import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;

import ru.vassaev.core.types.StringList;
import ru.vassaev.core.util.Bytes;
import ru.vassaev.core.io.CloseableOutputStream;
import ru.vassaev.core.io.ByteMsg;
import ru.vassaev.core.PrmInterface;

/**
* Сообщение формата CSNV (РУКАРД)
*
* @author Vassaev A.V.
* @version 1.1
*/
public class CSNVMsg extends ByteMsg {
  private Map<String, byte[]> btf = new TreeMap<String, byte[]>();
  private String character = "ibm866";
  private int ll = 2; //Длина буфера под длину сообщения
  private int len = 0; //Длина тела сообщения
  private byte delimiter = 0x1c;

  public CSNVMsg() {
  }

  public CSNVMsg(String character) {
    this.character = character;
  }

  public void reset() {
    btf.clear();
    len = 0;
  }

  /**
   * Получить длину только сообщения
   *
   * @return int
   */
  public int getLengthMsg() {
    return len;
  }

  /**
   * Получить полную длину сообщения, включая поля длины сообщения
   *
   * @return int
   */
  public int getLengthFull() {
    return getLengthMsg() + ll;
  }

  private void setField(byte[] val, int len) throws SysException {
    if ((val == null) || (val.length == 0)) {
      prms.clearField("");
      return;
    }
    String fld;
    try {
      fld = new String(val, 0, len, character);
    } catch (UnsupportedEncodingException ex) {
      throw new SysException(ex);
    }
    int p = fld.indexOf('=');
    if (p >= 0)
      prms.setField(fld.substring(0, p), fld.substring(p + 1));
    else
      prms.setField("", fld);
  }

  /**
   * Сообщение в виде последовательности массивов байт
   *
   * @return ArrayList
   */
  public ArrayList<byte[]> getMsg() {
    ArrayList<byte[]> ls = new ArrayList<byte[]>();
    Iterator<byte[]> itr = btf.values().iterator();
    int l = getLengthMsg();
    int fl = l + ll;
    byte[] v = new byte[fl];
    for (int i = ll - 1; i >= 0; i--) {
      v[i] = (byte) (l & 0xff);
      l = l >> 8;
    }
    int i = ll;
    while (itr.hasNext()) {
      byte[] val = itr.next();
      int s;
      if ((val != null) && ((s = val.length) > 0)) {
        System.arraycopy(val, 0, v, i, s);
        i = i + s;
        if (i < fl) {
          v[i] = delimiter;
          i++;
        }
      }
    }
    ls.add(v);
    return ls;
  }

  public String getKey() throws SysException {
    return prms.getField("STAN");
  }

  public void setKey(String key) throws SysException {
    prms.setField("STAN", key);
  }

  private class MessageOutputStream extends CloseableOutputStream {
    private int i = 0;
    private int pos = 0;
    private byte[] lengthb = new byte[ll];
    private byte[] current = new byte[2048];
    private int length = 0;

    public void write(int b) throws IOException {
      if (i < 0) // Если поток закрыт
        throw new IOException("The stream is already closed");
      if (i == 0) { // Общая длина - LL байт
        lengthb[pos] = (byte) b;
        pos++;
        if (pos == lengthb.length) {
          length = Bytes.byteReversToInt(lengthb);
          i++;
          pos = 0;
        }
        return;
      }
      byte bb = (byte) (b & 0xff);
      if (bb == delimiter) {
        try {
          setField(current, pos);
        } catch (SysException e) {
          throw new IOException(e.getMessage());
        }
        i++;
        pos = 0;
        length--;
        if (length <= 0) {
          close();
        }
      } else {
        current[pos] = bb;
        pos++;
        length--;
        if (length <= 0) {
          try {
            setField(current, pos);
          } catch (SysException e) {
            throw new IOException(e.getMessage());
          }
          close();
        }
      }
    }

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

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

  /**
   * Получить входящий поток сообщения
   *
   * @return OutputStream
   */
  public CloseableOutputStream getOutputStream() throws IOException {
    return new MessageOutputStream();
  }

  private final PrmInterface prms = new Prm();

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

  public class Prm implements PrmInterface {

    /**
     * Установить поле
     *
     * @param name String
     * @param val  byte[]
     */
    public void setField(String name, String val) throws SysException {
      if ((val == null) || (val.length() == 0)) {
        clearField(name);
        return;
      }
      String nm = name;//name.toUpperCase();
      byte[] n;
      try {
        nm = ((nm != null) && (nm.length() > 0)) ? nm + "=" : "";
        n = (nm + val).getBytes(character);
      } catch (UnsupportedEncodingException ex) {
        throw new RuntimeException(ex);
      }
      byte[] o = btf.put(name, n);
      if (o != null)
        len = len - o.length;
      else if (btf.size() > 1)
        len = len + 1;
      len += n.length;
    }

    /**
     * Очистить поле
     *
     * @param name String
     */
    public void clearField(String name) {
      byte[] o = (btf.remove(name/*.toUpperCase()*/));
      if (o != null) {
        len = len - o.length;
        if (btf.size() > 0)
          len = len - 1;
      }
    }

    public boolean isPresentField(String key) throws SysException {
      return btf.get(key/*.toUpperCase()*/) != null;
    }

    public void clearFields() throws SysException {
      ArrayList<String> flds = getFieldNames();
      for (int i = flds.size() - 1; i >= 0; i--)
        clearField(flds.get(i));
    }

    /**
     * Получить поле
     *
     * @param name String
     * @return byte[]
     */
    public String getField(String name) {
      byte[] o = btf.get(name);
      if (o == null)
        return null;
      String os;
      try {
        os = new String(o, 0, o.length, character);
      } catch (UnsupportedEncodingException ex) {
        throw new RuntimeException(ex);
      }
      int i = os.indexOf('=');
      if (i >= 0)
        return os.substring(i + 1);
      else
        return os;
    }

    public StringList getFieldNames() {
      StringList ls = new StringList();
      for (String s : btf.keySet())
        ls.add(s);
      return ls;
    }

    public byte[] getByteField(String key) throws SysException {
      // TODO Auto-generated method stub
      return null;
    }
  }

  public void sendTo(OutputStream os) throws IOException {
    ArrayList<byte[]> res = getMsg();
    if (res.size() == 1) {
      byte[] f = res.get(0);
      os.write(f);
      os.flush();
    }
  }
}
TOP

Related Classes of center.system.msg.CSNVMsg$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.