diff --git a/java_console/inifile/src/main/java/com/macfaq/io/LittleEndianOutputStream.java b/java_console/inifile/src/main/java/com/macfaq/io/LittleEndianOutputStream.java
new file mode 100644
index 0000000000..3c06319dd6
--- /dev/null
+++ b/java_console/inifile/src/main/java/com/macfaq/io/LittleEndianOutputStream.java
@@ -0,0 +1,294 @@
+/*
+ * @(#)LittleEndianOutputStream.java 1.0.1 99/05/19
+ *
+ * Copyright 1998, 1999 Elliotte Rusty Harold
+ *
+ */
+
+package com.macfaq.io;
+
+import java.io.*;
+
+/**
+ * A little endian output stream writes primitive Java numbers
+ * and characters to an output stream in a little endian format.
+ * The standard java.io.DataOutputStream class which this class
+ * imitates uses big-endian integers.
+ *
+ * @author Elliotte Rusty Harold
+ * @version 1.0.1, 19 May 1999
+ * @see com.macfaq.io.LittleEndianInputStream
+ * @see java.io.DataOutputStream
+ */
+public class LittleEndianOutputStream extends FilterOutputStream {
+
+ /**
+ * The number of bytes written so far to the little endian output stream.
+ */
+ protected int written;
+
+ /**
+ * Creates a new little endian output stream and chains it to the
+ * output stream specified by the out argument.
+ *
+ * @param out the underlying output stream.
+ * @see java.io.FilterOutputStream#out
+ */
+ public LittleEndianOutputStream(OutputStream out) {
+ super(out);
+ }
+
+ /**
+ * Writes the specified byte value to the underlying output stream.
+ *
+ * @param b the byte
value to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public synchronized void write(int b) throws IOException {
+ out.write(b);
+ written++;
+ }
+
+ /**
+ * Writes length
bytes from the specified byte array
+ * starting at offset
to the underlying output stream.
+ *
+ * @param data the data.
+ * @param offset the start offset in the data.
+ * @param length the number of bytes to write.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public synchronized void write(byte[] data, int offset, int length)
+ throws IOException {
+ out.write(data, offset, length);
+ written += length;
+ }
+
+
+ /**
+ * Writes a boolean
to the underlying output stream as
+ * a single byte. If the argument is true, the byte value 1 is written.
+ * If the argument is false, the byte value 0
in written.
+ *
+ * @param b the boolean
value to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeBoolean(boolean b) throws IOException {
+
+ if (b) this.write(1);
+ else this.write(0);
+
+ }
+
+ /**
+ * Writes out a byte
to the underlying output stream
+ *
+ * @param b the byte
value to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeByte(int b) throws IOException {
+ out.write(b);
+ written++;
+ }
+
+ /**
+ * Writes a two byte short
to the underlying output stream in
+ * little endian order, low byte first.
+ *
+ * @param s the short
to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeShort(int s) throws IOException {
+
+ out.write(s & 0xFF);
+ out.write((s >>> 8) & 0xFF);
+ written += 2;
+
+ }
+
+ /**
+ * Writes a two byte char
to the underlying output stream
+ * in little endian order, low byte first.
+ *
+ * @param c the char
value to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeChar(int c) throws IOException {
+
+ out.write(c & 0xFF);
+ out.write((c >>> 8) & 0xFF);
+ written += 2;
+
+ }
+
+ /**
+ * Writes a four-byte int
to the underlying output stream
+ * in little endian order, low byte first, high byte last
+ *
+ * @param i the int
to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeInt(int i) throws IOException {
+
+ out.write(i & 0xFF);
+ out.write((i >>> 8) & 0xFF);
+ out.write((i >>> 16) & 0xFF);
+ out.write((i >>> 24) & 0xFF);
+ written += 4;
+
+ }
+
+ /**
+ * Writes an eight-byte long
to the underlying output stream
+ * in little endian order, low byte first, high byte last
+ *
+ * @param l the long
to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeLong(long l) throws IOException {
+
+ out.write((int) l & 0xFF);
+ out.write((int) (l >>> 8) & 0xFF);
+ out.write((int) (l >>> 16) & 0xFF);
+ out.write((int) (l >>> 24) & 0xFF);
+ out.write((int) (l >>> 32) & 0xFF);
+ out.write((int) (l >>> 40) & 0xFF);
+ out.write((int) (l >>> 48) & 0xFF);
+ out.write((int) (l >>> 56) & 0xFF);
+ written += 8;
+
+ }
+
+ /**
+ * Writes a 4 byte Java float to the underlying output stream in
+ * little endian order.
+ *
+ * @param f the float
value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public final void writeFloat(float f) throws IOException {
+
+ this.writeInt(Float.floatToIntBits(f));
+
+ }
+
+ /**
+ * Writes an 8 byte Java double to the underlying output stream in
+ * little endian order.
+ *
+ * @param d the double
value to be written.
+ * @exception IOException if an I/O error occurs.
+ */
+ public final void writeDouble(double d) throws IOException {
+
+ this.writeLong(Double.doubleToLongBits(d));
+
+ }
+
+ /**
+ * Writes a string to the underlying output stream as a sequence of
+ * bytes. Each character is written to the data output stream as
+ * if by the writeByte()
method.
+ *
+ * @param s the String
value to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ * @see java.io.LittleEndianOutputStream#writeByte(int)
+ * @see java.io.LittleEndianOutputStream#out
+ */
+ public void writeBytes(String s) throws IOException {
+
+ int length = s.length();
+ for (int i = 0; i < length; i++) {
+ out.write((byte) s.charAt(i));
+ }
+ written += length;
+ }
+
+ /**
+ * Writes a string to the underlying output stream as a sequence of
+ * characters. Each character is written to the data output stream as
+ * if by the writeChar
method.
+ *
+ * @param s a String
value to be written.
+ * @exception IOException if the underlying stream throws an IOException.
+ * @see java.io.LittleEndianOutputStream#writeChar(int)
+ * @see java.io.LittleEndianOutputStream#out
+ */
+ public void writeChars(String s) throws IOException {
+
+ int length = s.length();
+ for (int i = 0; i < length; i++) {
+ int c = s.charAt(i);
+ out.write(c & 0xFF);
+ out.write((c >>> 8) & 0xFF);
+ }
+ written += length * 2;
+
+ }
+
+ /**
+ * Writes a string of no more than 65,535 characters
+ * to the underlying output stream using UTF-8
+ * encoding. This method first writes a two byte short
+ * in big endian order as required by the
+ * UTF-8 specification. This gives the number of bytes in the
+ * UTF-8 encoded version of the string, not the number of characters
+ * in the string. Next each character of the string is written
+ * using the UTF-8 encoding for the character.
+ *
+ * @param s the string to be written.
+ * @exception UTFDataFormatException if the string is longer than
+ * 65,535 characters.
+ * @exception IOException if the underlying stream throws an IOException.
+ */
+ public void writeUTF(String s) throws IOException {
+
+ int numchars = s.length();
+ int numbytes = 0;
+
+ for (int i = 0 ; i < numchars ; i++) {
+ int c = s.charAt(i);
+ if ((c >= 0x0001) && (c <= 0x007F)) numbytes++;
+ else if (c > 0x07FF) numbytes += 3;
+ else numbytes += 2;
+ }
+
+ if (numbytes > 65535) throw new UTFDataFormatException();
+
+ out.write((numbytes >>> 8) & 0xFF);
+ out.write(numbytes & 0xFF);
+ for (int i = 0 ; i < numchars ; i++) {
+ int c = s.charAt(i);
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ out.write(c);
+ }
+ else if (c > 0x07FF) {
+ out.write(0xE0 | ((c >> 12) & 0x0F));
+ out.write(0x80 | ((c >> 6) & 0x3F));
+ out.write(0x80 | (c & 0x3F));
+ written += 2;
+ }
+ else {
+ out.write(0xC0 | ((c >> 6) & 0x1F));
+ out.write(0x80 | (c & 0x3F));
+ written += 1;
+ }
+ }
+
+ written += numchars + 2;
+
+ }
+
+ /**
+ * Returns the number of bytes written to this little endian output stream.
+ * (This class is not thread-safe with respect to this method. It is
+ * possible that this number is temporarily less than the actual
+ * number of bytes written.)
+ * @return the value of the written
field.
+ * @see java.io.LittleEndianOutputStream#written
+ */
+ public int size() {
+ return this.written;
+ }
+
+}
\ No newline at end of file
diff --git a/java_console/inifile/src/main/java/com/rusefi/config/Field.java b/java_console/inifile/src/main/java/com/rusefi/config/Field.java
index 463836bee5..042e996983 100644
--- a/java_console/inifile/src/main/java/com/rusefi/config/Field.java
+++ b/java_console/inifile/src/main/java/com/rusefi/config/Field.java
@@ -1,9 +1,13 @@
package com.rusefi.config;
+import com.macfaq.io.LittleEndianOutputStream;
import com.opensr5.ConfigurationImage;
import org.jetbrains.annotations.NotNull;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.util.Objects;
import static com.rusefi.config.FieldType.*;
@@ -154,6 +158,29 @@ public class Field {
return options[ordinal];
}
+ public void setValue(byte[] content, boolean value) {
+ ByteBuffer wrapped = ByteBuffer.wrap(content, 0, content.length);
+ wrapped.order(ByteOrder.LITTLE_ENDIAN);
+ if (bitOffset != NO_BIT_OFFSET) {
+ int packed = wrapped.getInt();
+ int thisBit = (value ? 1 : 0) << bitOffset;
+ int mask = 1 << bitOffset;
+ int newValue = (packed & ~mask) | thisBit;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ LittleEndianOutputStream dout = new LittleEndianOutputStream(baos);
+ // wow worst way to modify an integer in byte array? :)
+ try {
+ dout.writeInt(newValue);
+// dout.flush();
+ byte[] src = baos.toByteArray();
+ System.arraycopy(src, 0, content, getOffset(), 4);
+ baos.close();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
/**
* each usage is a potential bug?! we are supposed to have explicit multiplier for each field
*/
@@ -196,8 +223,7 @@ public class Field {
}
public static Field create(String name, int offset, FieldType type, int bitOffset) {
- Field field = new Field(name, offset, type, bitOffset);
- return field;
+ return new Field(name, offset, type, bitOffset);
}
public static Field create(String name, int offset, FieldType type, String... options) {
@@ -210,8 +236,7 @@ public class Field {
}
public static Field create(String name, int offset, FieldType type) {
- Field field = new Field(name, offset, type);
- return field;
+ return new Field(name, offset, type);
}
public String getStringValue(ConfigurationImage image) {
@@ -223,4 +248,8 @@ public class Field {
bb.get(bytes);
return new String(bytes).trim();
}
+
+ public boolean getBooleanValue(ConfigurationImage ci) {
+ return getValue(ci) != 0.0;
+ }
}
\ No newline at end of file
diff --git a/java_console/models/src/test/java/com/rusefi/config/test/FieldTest.java b/java_console/models/src/test/java/com/rusefi/config/test/FieldTest.java
index 70d5952834..2c18d7035b 100644
--- a/java_console/models/src/test/java/com/rusefi/config/test/FieldTest.java
+++ b/java_console/models/src/test/java/com/rusefi/config/test/FieldTest.java
@@ -1,13 +1,13 @@
package com.rusefi.config.test;
+import com.opensr5.ConfigurationImage;
import com.rusefi.config.Field;
import com.rusefi.config.FieldCommandResponse;
+import com.rusefi.config.generated.Fields;
import com.rusefi.core.Pair;
import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+import static org.junit.Assert.*;
public class FieldTest {
@Test
@@ -30,17 +30,39 @@ public class FieldTest {
}
@Test
- public void testPrecisionDependingOnScale() {
- assertEquals("0.12302", Field.niceToString(0.12302, 4));
- assertEquals("0.1232", Field.niceToString(0.12317, 3));
+ public void setBooleanValue() {
+ byte[] config = new byte[Fields.persistent_config_s_size];
+ ConfigurationImage ci = new ConfigurationImage(config);
- assertEquals("1234567.1", Field.niceToString(1234567.123, 4));
- assertEquals("10000.0", Field.niceToString(10000.00002, 4));
- assertEquals("0.002", Field.niceToString(0.002, 4));
- assertEquals("12.302", Field.niceToString(12.302, 4));
- assertEquals("12.302", Field.niceToString(12.302, 3));
- assertEquals("12.31", Field.niceToString(12.312, 2));
- assertEquals("123.02", Field.niceToString(123.02, 4));
+ assertFalse(Fields.ISFORCEDINDUCTION.getBooleanValue(ci));
+ assertFalse(Fields.OVERRIDETRIGGERGAPS.getBooleanValue(ci));
+ assertFalse(Fields.ENABLEFAN1WITHAC.getBooleanValue(ci));
+
+ Fields.OVERRIDETRIGGERGAPS.setValue(config, true);
+
+ assertFalse(Fields.ISFORCEDINDUCTION.getBooleanValue(ci));
+ assertTrue(Fields.OVERRIDETRIGGERGAPS.getBooleanValue(ci));
+ assertFalse(Fields.ENABLEFAN1WITHAC.getBooleanValue(ci));
+
+ Fields.OVERRIDETRIGGERGAPS.setValue(config, false);
+
+ assertFalse(Fields.ISFORCEDINDUCTION.getBooleanValue(ci));
+ assertFalse(Fields.OVERRIDETRIGGERGAPS.getBooleanValue(ci));
+ assertFalse(Fields.ENABLEFAN1WITHAC.getBooleanValue(ci));
+ }
+
+ @Test
+ public void testPrecisionDependingOnScale() {
+ assertEquals("0.12302", Field.niceToString(0.12302, 4));
+ assertEquals("0.1232", Field.niceToString(0.12317, 3));
+
+ assertEquals("1234567.1", Field.niceToString(1234567.123, 4));
+ assertEquals("10000.0", Field.niceToString(10000.00002, 4));
+ assertEquals("0.002", Field.niceToString(0.002, 4));
+ assertEquals("12.302", Field.niceToString(12.302, 4));
+ assertEquals("12.302", Field.niceToString(12.302, 3));
+ assertEquals("12.31", Field.niceToString(12.312, 2));
+ assertEquals("123.02", Field.niceToString(123.02, 4));
}
}