// // Copyright (C) 2008 United States Government as represented by the // Administrator of the National Aeronautics and Space Administration // (NASA). All Rights Reserved. // // This software is distributed under the NASA Open Source Agreement // (NOSA), version 1.3. The NOSA has been approved by the Open Source // Initiative. See the file NOSA-1.3-JPF at the top of the distribution // directory tree for the complete NOSA document. // // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.vm; import java.io.PrintStream; import java.util.Arrays; import java.util.function.BiFunction; import cmu.conditional.ChoiceFactory; import cmu.conditional.Conditional; import java.util.function.Function; import cmu.conditional.One; import de.fosd.typechef.featureexpr.FeatureExpr; import gov.nasa.jpf.util.HashData; import gov.nasa.jpf.util.IntVector; import gov.nasa.jpf.util.PrintUtils; /** * element values for char[] objects */ public class CharArrayFields extends ArrayFields { private Conditional<char[]> values; public CharArrayFields(int length) { values = new One<>(new char[length]); } public Conditional<char[]> asCharArray() { return values; } @Override protected void printValue(PrintStream ps, int idx) { PrintUtils.printCharLiteral(ps, values.getValue()[idx]); } @Override public void printElements(PrintStream ps, int max) { PrintUtils.printStringLiteral(ps, values.getValue(), max); } public char[] asCharArray(int offset, int length) { char[] result = new char[length]; System.arraycopy(values.getValue(), offset, result, 0, length); return result; } public Conditional<?> getValues() { return values; } public Conditional<Integer> arrayLength() { return values.mapr(ArrayLength).simplifyValues(); } private static final Function<char[], Conditional<Integer>> ArrayLength = new Function<char[], Conditional<Integer>>() { @Override public Conditional<Integer> apply(char[] values) { return new One<>(values.length); } }; public int getHeapSize() { // in bytes return values.getValue().length * 2; } public void appendTo(IntVector v) {// TODO Jens seems to be no good idea for (char[] value : values.toList()) { v.appendPacked(value); } } public CharArrayFields clone() { CharArrayFields f = (CharArrayFields) cloneFields(); try { f.values = values.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return f; } public boolean equals(Object o) { if (o instanceof CharArrayFields) { CharArrayFields other = (CharArrayFields) o; char[] v = values.getValue(); char[] vOther = other.values.getValue(); if (v.length != vOther.length) { return false; } for (int i = 0; i < v.length; i++) { if (v[i] != vOther[i]) { return false; } } return compareAttrs(other); } else { return false; } } public Conditional<Character> getCharValue(final int pos) { return values.map(new Function<char[], Character>() { @Override public Character apply(char[] values) { return values[pos]; } }); } @Override public void setCharValue(final FeatureExpr ctx, final int pos, final Conditional<Character> newValue) { values = values.mapf(ctx, new BiFunction<FeatureExpr, char[], Conditional<char[]>>() { @Override public Conditional<char[]> apply(final FeatureExpr ctx2, final char[] values) { if (Conditional.isContradiction(ctx2)) { return new One<>(values); } return newValue.mapf(ctx2, new BiFunction<FeatureExpr, Character, Conditional<char[]>>() { @Override public Conditional<char[]> apply(FeatureExpr f, Character newValue) { if (Conditional.isContradiction(f)) { return new One<>(values); } if (Conditional.isTautology(f)) { values[pos] = newValue; return new One<>(values); } char[] clone = new char[values.length]; System.arraycopy(values, 0, clone, 0, clone.length); clone[pos] = newValue; return ChoiceFactory.create(ctx, new One<>(clone), new One<>(values)); } }); } }).simplify(); } public void setCharValues(FeatureExpr ctx, char[] v) { char[] newValues = new char[v.length]; System.arraycopy(v, 0, newValues, 0, v.length); if (ctx == null) { throw new RuntimeException("ctx == null"); } if (Conditional.isTautology(ctx)) { values = new One<>(newValues); } else { values = ChoiceFactory.create(ctx, new One<>(newValues), values).simplify(); } } // --- some methods to ease native String operations public String asString(int offset, int length) { return new String(values.getValue(), offset, length); } // a special string compare utility public boolean equals(int offset, int length, String s) { char[] v = values.getValue(); if (offset + length > v.length) { return false; } for (int i = offset, j = 0; j < length; i++, j++) { if (v[i] != s.charAt(j)) { return false; } } return true; } public void hash(HashData hd) { char[] v = values.getValue(); for (int i = 0; i < v.length; i++) { hd.add(v[i]); } } @Override public void fill(FeatureExpr ctx, final Conditional<?> value) { if (Conditional.isTautology(ctx) && value.isOne()) { final char[] newArray = new char[values.getValue(true).length]; Arrays.fill(newArray, (Character) value.getValue()); values = new One<char[]>(newArray); } values = values.mapf(ctx, new BiFunction<FeatureExpr, char[], Conditional<char[]>>() { @Override public Conditional<char[]> apply(FeatureExpr ctx, char[] y) { final Character c = (Character) value.simplify(ctx).getValue(); final char[] newArray = new char[y.length]; Arrays.fill(newArray, c); if (Conditional.isTautology(ctx)) { return new One<char[]>(newArray); } return ChoiceFactory.create(ctx, new One<char[]>(newArray), new One<char[]>(y)); } }); } }