Skip to content

Commit

Permalink
feat(objectionary#976): add DirectivesNumberValue
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Jan 21, 2025
1 parent 8c4c244 commit 607f091
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ enum DataType {
* Byte.
*/
BYTE("byte", Byte.class,
value -> ByteBuffer.allocate(Byte.BYTES).put((byte) (int) value).array(),
value -> ByteBuffer.allocate(Byte.BYTES).put((byte) value).array(),
bytes -> ByteBuffer.wrap(bytes).get()
),

/**
* Short.
*/
SHORT("short", Short.class,
value -> ByteBuffer.allocate(Short.BYTES).putShort((short) (int) value).array(),
value -> ByteBuffer.allocate(Short.BYTES).putShort((short) value).array(),
bytes -> ByteBuffer.wrap(bytes).getShort()
),

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2025 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.eolang.jeo.representation.directives;

import java.util.Iterator;
import org.eolang.jeo.representation.bytecode.BytecodeValue;
import org.xembly.Directive;
import org.xembly.Directives;

public final class DirectivesNumberBytes implements Iterable<Directive> {

/**
* Array of hexadecimal characters.
* Used for converting bytes to hexadecimal.
* See {@link #bytesToHex(byte[])}.
*/
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();

private final Number number;

public DirectivesNumberBytes(final Number number) {
this.number = number;
}

@Override
public Iterator<Directive> iterator() {
return new Directives()
.add("o")
.attr("base", "org.eolang.number")
.append(new DirectivesBytes(this.bytes()))
.up()
.iterator();
}

private String bytes() {
return DirectivesNumberBytes.bytesToHex(
new BytecodeValue(this.number.doubleValue()).bytes());
}

/**
* @todo Duplicate!
*/
private static String bytesToHex(final byte[] bytes) {
final String res;
if (bytes == null || bytes.length == 0) {
res = "--";
} else {
final int length = bytes.length;
final char[] hex = new char[length * 3];
for (int index = 0; index < length; ++index) {
final int value = bytes[index] & 0xFF;
hex[index * 3] = HEX_ARRAY[value >>> 4];
hex[index * 3 + 1] = HEX_ARRAY[value & 0x0F];
hex[index * 3 + 2] = '-';
}
if (hex.length == 3) {
res = new String(hex);
} else {
res = new String(hex, 0, hex.length - 1);
}
}
return res;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,54 @@ public DirectivesValue(final String name, final BytecodeValue value) {
public Iterator<Directive> iterator() {
final String type = this.type();
final Iterable<Directive> res;
if ("string".equals(type)) {
res = new DirectivesEoObject(
type,
this.name,
new DirectivesComment(this.comment()),
new DirectivesBytes(this.hex())
);
} else {
res = new DirectivesJeoObject(
type,
this.name,
new DirectivesComment(this.comment()),
new DirectivesBytes(this.hex())
);
switch (type) {
case "byte":
case "short":
case "int":
case "long":
case "float":
case "double":
res = new DirectivesJeoObject(
type,
this.name,
new DirectivesComment(this.comment()),
new DirectivesNumberBytes((Number) this.value.object())
);
break;
case "string":
res = new DirectivesEoObject(
type,
this.name,
new DirectivesComment(this.comment()),
new DirectivesBytes(this.hex())
);
break;
default:
res = new DirectivesJeoObject(
type,
this.name,
new DirectivesComment(this.comment()),
new DirectivesBytes(this.hex())
);
break;
}
return res.iterator();
// if ("string".equals(type)) {
// res = new DirectivesEoObject(
// type,
// this.name,
// new DirectivesComment(this.comment()),
// new DirectivesBytes(this.hex())
// );
// } else {
// res = new DirectivesJeoObject(
// type,
// this.name,
// new DirectivesComment(this.comment()),
// new DirectivesBytes(this.hex())
// );
// }
// return res.iterator();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2016-2025 Objectionary.com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.eolang.jeo.representation.directives;

import com.jcabi.matchers.XhtmlMatchers;
import java.util.stream.Stream;
import org.hamcrest.MatcherAssert;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.xembly.ImpossibleModificationException;
import org.xembly.Xembler;

/**
* Test case for {@link DirectivesNumberBytes}.
* @since 0.8
*/
final class DirectivesNumberBytesTest {

@ParameterizedTest
@MethodSource("numbers")
void convertsDifferentNumbersToBytes(
final Number value, final String bytes
) throws ImpossibleModificationException {
final String xml = new Xembler(new DirectivesNumberBytes(value)).xml();
MatcherAssert.assertThat(
String.format(
"We expect that number will be converted to the correct XMIR, but got: %n%s%n",
xml
),
xml,
XhtmlMatchers.hasXPaths(
"/o[@base='org.eolang.number']",
String.format(
"/o[@base='org.eolang.number']/o[@base='org.eolang.bytes' and text()='%s']",
bytes
)
)
);
}

/**
* Provide numbers.
* @return Numbers.
*/
static Stream<Arguments> numbers() {
final String same = "3F-F0-00-00-00-00-00-00";
return Stream.of(
Arguments.of(1, same),
Arguments.of(1L, same),
Arguments.of(1.0, same),
Arguments.of(1.0f, same),
Arguments.of(1.0d, same),
Arguments.of((byte) 1, same),
Arguments.of((short) 1, same)
);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
package org.eolang.jeo.representation.directives;

import com.jcabi.matchers.XhtmlMatchers;
import java.util.stream.Stream;
import org.eolang.jeo.matchers.SameXml;
import org.eolang.jeo.representation.bytecode.BytecodeLabel;
Expand Down Expand Up @@ -65,20 +66,21 @@ void convertsInteger() throws ImpossibleModificationException {
void convertsNumbers(
Number number, final String base, final String bytes
) throws ImpossibleModificationException {
final String xml = new Xembler(new DirectivesValue("access", number)).xml();
MatcherAssert.assertThat(
"We expect that number value is converted to the correct XMIR",
new Xembler(new DirectivesValue(base, number)).xml(),
new SameXml(
String.join(
"\n",
String.format("<o base='%s' as='access'>", base),
"<o base='org.eolang.number'>",
String.format(" <o base='org.eolang.bytes'>%s</o>", bytes),
"</o></o>"
String.format(
"We expect that number value is converted to the correct XMIR, but got the incorrect one: %n%s%n",
xml
),
xml,
XhtmlMatchers.hasXPath(
String.format(
"./o[@base='%s' and @as='access']/o[@base='org.eolang.number']/o[@base='org.eolang.bytes' and text()='%s']",
base,
bytes
)
)
);

}

@Test
Expand Down Expand Up @@ -224,13 +226,14 @@ static Stream<Arguments> values() {
* @return Stream of arguments.
*/
static Stream<Arguments> numbers() {
final String same = "3F-F0-00-00-00-00-00-00";
return Stream.of(
Arguments.of(1, "jeo.int", "00-00-00-00-00-00-00-01"),
Arguments.of(1L, "jeo.long", "00-00-00-00-00-00-00-01"),
Arguments.of(1.0f, "jeo.float", "3F-80-00-00"),
Arguments.of(1.0d, "jeo.double", "3F-F0-00-00-00-00-00-00"),
Arguments.of((short) 1, "jeo.short", "00-01"),
Arguments.of((byte) 1, "jeo.byte", "01")
Arguments.of(1, "jeo.int", same),
Arguments.of(1L, "jeo.long", same),
Arguments.of(1.0f, "jeo.float", same),
Arguments.of(1.0d, "jeo.double", same),
Arguments.of((short) 1, "jeo.short", same),
Arguments.of((byte) 1, "jeo.byte", same)
);
}
}

0 comments on commit 607f091

Please sign in to comment.