001package jmri.jmrix.srcp;
002
003import jmri.jmrix.srcp.parser.SimpleNode;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * Carries the reply to an SRCPMessage.
009 *
010 * @author Bob Jacobsen Copyright (C) 2001, 2004, 2008
011 */
012public class SRCPReply extends jmri.jmrix.AbstractMRReply {
013
014    // create a new one
015    public SRCPReply() {
016        super();
017    }
018
019    public SRCPReply(String s) {
020        super(s);
021    }
022
023    public SRCPReply(SRCPReply l) {
024        super(l);
025    }
026
027    // from a parser message node.
028    public SRCPReply(SimpleNode n) {
029        super();
030        log.debug("Parser Constructor called with node type {} and {} children.", n.getClass(), n.jjtGetNumChildren());
031        String s = inOrderTraversal(n);
032        log.debug("Parser Constructor built :{}", s);
033        _nDataChars = s.length();
034        for (int i = 0; i < _nDataChars; i++) {
035            _dataChars[i] = s.charAt(i);
036        }
037    }
038
039    private String inOrderTraversal(SimpleNode n) {
040        StringBuilder b;
041        if (n.jjtGetNumChildren() > 1) {
042            b = new StringBuilder((String) n.jjtGetValue());
043            for (int i = 0; i < n.jjtGetNumChildren(); i++) {
044                if (i != 0) {
045                    b.append(" ");
046                }
047                b.append(inOrderTraversal((SimpleNode) n.jjtGetChild(i)));
048            }
049        } else {
050            try {
051                b = new StringBuilder((String) n.jjtGetValue());
052            } catch (java.lang.NullPointerException npe) {
053                b = new StringBuilder("");
054            }
055        }
056        return b.toString();
057    }
058
059    public boolean isResponseOK() {
060        return getResponseCode().charAt(0) == '1' || getResponseCode().charAt(0) == '2';
061    }
062
063    public String getResponseCode() {
064        // split into 3 parts {TIMESTAMP, ResponseCode, Rest}
065        // and use the second one (ResponseCode)
066        String[] part = toString().split("\\s", 3);
067        return part[1];
068    }
069
070    @Override
071    protected int skipPrefix(int index) {
072        // start at index, passing any whitespace & control characters at the start of the buffer
073        while (index < getNumDataElements() - 1
074                && ((char) getElement(index) <= ' ')) {
075            index++;
076        }
077        return index;
078    }
079
080    /**
081     * Extracts Read-CV returned value from a message. Returns -1 if message
082     * can't be parsed. Expects a message of the form 1264343601.156 100 INFO 1
083     * SM -1 CV 8 99
084     */
085    @Override
086    public int value() {
087        String s = toString();
088        String[] part = s.split("\\s", 10);
089        int val = -1;
090
091        try {
092            int tmp = Integer.valueOf(part[7], 10).intValue();
093            val = tmp;  // don't do this assign until now in case the conversion throws
094        } catch (Exception e) {
095            log.error("Unable to get number from reply: \"{}\"", s);
096        }
097        return val;
098    }
099
100    @Override
101    public boolean isUnsolicited() {
102        String s = toString();
103        try {
104            // Split in 7 is enough for initial handshake 
105            String[] part = s.split("\\s", 7);
106            // Test for initial handshake message with key "SRCP".
107            if (part[2].equals("SRCP")) {
108                setUnsolicited();
109                return true;
110            } else {
111                // the string wasn't long enough to split.
112                return false;
113            }
114        } catch (Exception e) {
115            return false;
116        }
117    }
118
119    private final static Logger log = LoggerFactory.getLogger(SRCPReply.class);
120
121}
122
123
124