Package code316.charlotte

Source Code of code316.charlotte.DefaultEncoding

package code316.charlotte;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.nfunk.jep.JEP;

import code316.core.PropertiesUtil;

public class DefaultEncoding implements Encoding {
    private ArrayList fieldNames = new ArrayList();
    private int bitCount;
    private ArrayList fieldDefinitions = new ArrayList();
    private String encodingName = "UNNAMED";
   
    public DefaultEncoding() {}
   
    private List getNames() {
        return (List) this.fieldNames.clone();       
    }
   
    public int getLength() {
        return this.bitCount;
    }
   

    public List getFieldDefinitions() {
        return (List) this.fieldDefinitions.clone();
    }
   
    private BigInteger extractFieldValue(String name, BigInteger bi) {
        int count = 0;
        Iterator tor = this.fieldNames.iterator();
        while (tor.hasNext()) {
            if (tor.next().equals(name)) {
                return extractFieldValue(count, bi);
            }
            count++;
        }
       
        throw new IllegalArgumentException("field named: '" + name + "' not found");
    }
   
    public BigInteger extractFieldValue(int i, BigInteger bi) {
        DefaultDefinition fd = (DefaultDefinition) this.fieldDefinitions.get(i);
        return bi.shiftRight(fd.getOffset()).and(EncodingUtil.getMaxValue(fd.getWidth()));
    }
   
   
    public BigInteger getMaxValue() {
        return EncodingUtil.getMaxValue(getLength());           
    }
   
    private String dumpValues(BigInteger bi) {
        int count = this.fieldDefinitions.size();
       
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            DefaultDefinition fd = (DefaultDefinition) this.fieldDefinitions.get(i);
            sb.append(fd.getName())
                .append("=")
                .append(extractFieldValue(i, bi))
                .append("\n");
        }
       
        return sb.toString();
    }
   
    private String dumpFields() {
        int count = this.fieldDefinitions.size();
   
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            DefaultDefinition fd = (DefaultDefinition) this.fieldDefinitions.get(i);
            sb.append(fd).append("\n");
        }
   
        return sb.toString();
    }
   
    private BigInteger encode(Map values) {       
        BigInteger encoded = new BigInteger("0");
        Iterator tor = this.fieldDefinitions.iterator();
       
        while (tor.hasNext()) {
            DefaultDefinition fd = (DefaultDefinition) tor.next();
            Object o = values.get(fd.getName());

            if ( o == null ) {
                continue;
            }

            BigInteger val = null;
           
            if ( o instanceof BigInteger ) {
                val = (BigInteger) o;               
            }
            else {
                val = new BigInteger(String.valueOf(o));               
            }

            if ( val.longValue() > EncodingUtil.getMaxValue(fd.getWidth()).longValue()) {
                throw new IllegalArgumentException("value to large for field width: " + val);           
            }
           
            encoded = encoded.or(val.shiftLeft(fd.getOffset()));
        }
       
        return encoded;
    }
   

    private FieldDefinition getField(String name) {
        int count = this.fieldDefinitions.size();
        for (int i = 0; i < count; i++) {
            DefaultDefinition fd = (DefaultDefinition) this.fieldDefinitions.get(i);
            if ( fd.getName().equals(name) ) {
                return fd;
            }           
        }

        return null;
    }
   
    private FieldDefinition getField(int index) {
        if ( index < 0 || index >= this.fieldDefinitions.size() ) {
            return null;
        }
       
        return (FieldDefinition) this.fieldDefinitions.get(index);
    }

    public double expandFieldValue(int index, BigInteger bits) {       
        FieldDefinition fd = getField(index);
        BigInteger raw = extractFieldValue(fd.getName(), bits);
        String expression = fd.getOperands();
        JEP expressionParser = new JEP();
       
       
        if PropertiesUtil.isEmpty(expression) ) {
            return raw.doubleValue();
        }
      
       
        if (expression.indexOf('[') != -1 ) {
            // this is a look up expresion
            double []vals = parseLookupTable(expression);
           
            return vals[raw.intValue()];       
        }
       
        List ids = parseIdentifiers(expression);
       
        if ( ids.size() != 0 ) {
            expression = removeIdentifiers(expression);
           
            Iterator tor = ids.iterator();
            while (tor.hasNext()) {
                String idName = (String) tor.next();
                FieldDefinition fieldDefinition = (FieldDefinition) getField(idName);
               
                if ( fieldDefinition == null ) {
                    throw new IllegalArgumentException("unknown field: " + idName);
                }
               
                if ( fieldDefinition.getOffset() < fd.getOffset() ) {
                    throw new IllegalStateException("cannot access downstream field: " + idName);
                }
               
                expressionParser.addVariable(idName, expandFieldValue(fieldDefinition.getIndex(), bits));               
            }
        }
       
        expressionParser.addVariable("x", raw.floatValue());
        expressionParser.addVariable("fieldWidth", fd.getWidth());
        expressionParser.addVariable("maxValue", EncodingUtil.getMaxValue(fd.getWidth()).floatValue());
        expressionParser.parseExpression(expression);
       
        
        return expressionParser.getValue();       
    }
   

    private String removeIdentifiers(String expression) {
        StringBuffer sb = new StringBuffer(expression.length());
        char []buffer = expression.toCharArray();
        for (int i = 0; i < buffer.length; i++) {
            char ch = buffer[i];
           
            if ( ch != '$' && ch != '{' && ch != '}' ) {
                sb.append(ch);
            }
        }
        return sb.toString();
    }

    private List parseIdentifiers(String expression) {
        int begin = expression.indexOf("${");
        List ids = new ArrayList(1);
       
        while (begin != -1) {
            int end = expression.indexOf("}", begin + 2);
            String name = expression.substring(begin + 2, end);
           
            if ( !ids.contains(name) ) {
                ids.add(name);
            }
           
            begin = expression.indexOf("${",  end);           
        }
       
        return ids;
    }

    /**
     * Parse a string into an array of doubles
     * e.g. string: [2.3, 1, 4.5]
     */
    private double[] parseLookupTable(String expression) {
        int start = expression.indexOf('[');
        int stop = expression.indexOf(']');
       
        if ( start == -1 || stop == -1 || start > stop ) {
            throw new IllegalArgumentException("invalid table definition: " + expression);
        }
               
        String def = expression.substring(start + 1, stop).trim();
        StringTokenizer st = new StringTokenizer(def, ",");
        double []vals = new double[st.countTokens()];       
       
        int i = 0;
       
        while (st.hasMoreTokens()) {
            vals[i] = Double.parseDouble(st.nextToken());
            i++;
        }
       
        return vals;
    }

    public String getName() {
        return encodingName;
    }

    public void setName(String name) {
        this.encodingName = name;
    }

    public void addFieldDefinition(FieldDefinition def) {
        DefaultEncoding.this.fieldNames.add(def.getName());
        DefaultEncoding.this.fieldDefinitions.add(def);
        this.bitCount += def.getWidth();
    }

   

    public FieldDefinition getFieldDefinition(int index) {
        return (FieldDefinition) this.fieldDefinitions.get(index);
    }

    public int getFieldCount() {
        return this.fieldDefinitions.size();
    }       
}
TOP

Related Classes of code316.charlotte.DefaultEncoding

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.