public synchronized int unpack(ISOComponent c, byte[] b) throws ISOException {
    LogEvent evt = new LogEvent(this, "unpack");
    try {
      if (!(c instanceof ISOMsg)) throw new ISOException("Can't call packager on non Composite");

      stk.clear();

      InputSource src = new InputSource(new ByteArrayInputStream(b));
      reader.parse(src);
      if (stk.empty()) throw new ISOException("error parsing");

      ISOMsg m = (ISOMsg) c;
      m.merge((ISOMsg) stk.pop());

      if (logger != null) evt.addMessage(m);
      return b.length;
    } catch (ISOException e) {
      evt.addMessage(e);
      throw e;
    } catch (IOException e) {
      evt.addMessage(e);
      throw new ISOException(e.toString());
    } catch (SAXException e) {
      evt.addMessage(e);
      throw new ISOException(e.toString());
    } finally {
      Logger.log(evt);
    }
  }
  public synchronized void unpack(ISOComponent c, InputStream in) throws ISOException, IOException {
    LogEvent evt = new LogEvent(this, "unpack");
    try {
      if (!(c instanceof ISOMsg)) throw new ISOException("Can't call packager on non Composite");

      while (!stk.empty())
        // purge from possible previous error
        stk.pop();

      reader.parse(new InputSource(in));
      if (stk.empty()) throw new ISOException("error parsing");

      ISOMsg m = (ISOMsg) c;
      m.merge((ISOMsg) stk.pop());

      if (logger != null) evt.addMessage(m);
    } catch (ISOException e) {
      evt.addMessage(e);
      throw e;
    } catch (SAXException e) {
      evt.addMessage(e);
      throw new ISOException(e.toString());
    } finally {
      Logger.log(evt);
    }
  }
 public byte[] pack(ISOComponent c) throws ISOException {
   LogEvent evt = new LogEvent(this, "pack");
   try {
     if (!(c instanceof ISOMsg)) throw new ISOException("cannot pack " + c.getClass());
     ISOMsg m = (ISOMsg) c;
     byte[] b;
     synchronized (this) {
       m.setDirection(0); // avoid "direction=xxxxxx" in XML msg
       m.dump(p, "");
       b = out.toByteArray();
       out.reset();
     }
     if (logger != null) evt.addMessage(m);
     return b;
   } catch (ISOException e) {
     evt.addMessage(e);
     throw e;
   } finally {
     Logger.log(evt);
   }
 }
  public void startElement(String ns, String name, String qName, Attributes atts)
      throws SAXException {
    int fieldNumber = -1;
    try {
      String id = atts.getValue(ID_ATTR);
      if (id != null) {
        try {
          fieldNumber = Integer.parseInt(id);
        } catch (NumberFormatException ex) {
        }
      }
      if (name.equals(ISOMSG_TAG)) {
        if (fieldNumber >= 0) {
          if (stk.empty()) throw new SAXException("inner without outter");

          ISOMsg inner = new ISOMsg(fieldNumber);
          ((ISOMsg) stk.peek()).set(inner);
          stk.push(inner);
        } else {
          stk.push(new ISOMsg(0));
        }
      } else if (name.equals(ISOFIELD_TAG)) {
        ISOMsg m = (ISOMsg) stk.peek();
        String value = atts.getValue(VALUE_ATTR);
        String type = atts.getValue(TYPE_ATTR);
        if (id == null || value == null) throw new SAXException("invalid field");
        if (TYPE_BINARY.equals(type)) {
          m.set(
              new ISOBinaryField(
                  fieldNumber, ISOUtil.hex2byte(value.getBytes(), 0, value.length() / 2)));
          //          m.set(new ISOBinaryField(fieldNumber, value.getBytes()));
        } else {
          m.set(new ISOField(fieldNumber, value));
        }
      }
    } catch (ISOException e) {
      throw new SAXException("ISOException unpacking " + fieldNumber);
    }
  }