001package jmri.jmrix;
002
003import java.util.Objects;
004import javax.annotation.Nonnull;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008/**
009 * Base for various message implementations used by the
010 * various abstract TrafficController classes.
011 *
012 * @author Bob Jacobsen Copyright 2007, 2008
013 */
014public abstract class AbstractMessage implements Message {
015
016    /**
017     * Create a new instance of AbstractMessage.
018     */
019    public AbstractMessage() {
020    }
021
022    /**
023     * Create a new instance of AbstractMessage of a given byte size.
024     *
025     * @param n number of elements
026     */
027    public AbstractMessage(int n) {
028        if (n < 1) {
029            log.error("invalid length in call to ctor");
030        }
031        _nDataChars = n;
032        _dataChars = new int[n];
033    }
034
035    public AbstractMessage(String s) {
036        this(s.length());
037        for (int i = 0; i < _nDataChars; i++) {
038            _dataChars[i] = s.charAt(i);
039        }
040    }
041
042    public AbstractMessage(@Nonnull AbstractMessage m) {
043        Objects.requireNonNull(m, "Unable to create message by copying null message");
044        _nDataChars = m._nDataChars;
045        _dataChars = new int[_nDataChars];
046        System.arraycopy(m._dataChars, 0, _dataChars, 0, _nDataChars);
047    }
048
049    /**
050     * {@inheritDoc}
051     */
052    @Override
053    public int getElement(int n) {
054        return _dataChars[n];
055    }
056
057    // accessors to the bulk data
058
059    /**
060     * {@inheritDoc}
061     */
062    @Override
063    public int getNumDataElements() {
064        return _nDataChars;
065    }
066
067    /**
068     * {@inheritDoc}
069     */
070    @Override
071    public void setElement(int n, int v) {
072        _dataChars[n] = v;
073    }
074
075    // display format
076    protected int[] _dataChars = null;
077
078    // display format
079    // contents (private)
080    protected int _nDataChars = 0;
081
082
083    /**
084     * Equals operator compares only base data.
085     */
086    @Override
087    public boolean equals(Object obj){
088        if (obj == null) return false; // basic contract
089        if( this.getClass() != obj.getClass() ) {
090            return false;
091        }
092        AbstractMessage m = (AbstractMessage) obj;
093        if(this.getNumDataElements() != m.getNumDataElements()){
094            return false;
095        }
096        for(int i = 0;i<this.getNumDataElements();i++){
097            if(this.getElement(i) != m.getElement(i)){
098                return false;
099            }
100        }
101        return true;
102    }
103
104    /**
105     * Hash code from base data.
106     * @return hashcode from sum of elements.
107     */
108    @Override
109    public int hashCode() {
110        int retval = 0;
111        for(int i = 0;i<this.getNumDataElements();i++){
112            retval += this.getElement(i);
113        }
114        return retval;
115    }
116
117    private final static Logger log = LoggerFactory.getLogger(AbstractMessage.class);
118
119}