SchubfachWriteCharBufferTest.java
package tools.jackson.core.unittest.io.schubfach;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import org.junit.jupiter.api.Test;
import tools.jackson.core.io.NumberOutput;
import static org.junit.jupiter.api.Assertions.*;
/**
* Tests for {@link NumberOutput#outputFloat(float, char[], int)} and
* {@link NumberOutput#outputDouble(double, char[], int)} which write directly
* to a char buffer, avoiding String allocation.
*/
public class SchubfachWriteCharBufferTest
{
@Test
public void testWriteFloatBasic()
{
float[] values = {
0.0f, -0.0f, 1.0f, -1.0f, 1.5f, -1.5f,
123.456f, -123.456f, 1.0E10f, 1.0E-10f,
Float.MAX_VALUE, Float.MIN_VALUE, Float.MIN_NORMAL,
Float.NaN, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY
};
for (float v : values) {
_verifyFloat(v);
}
}
@Test
public void testWriteDoubleBasic()
{
double[] values = {
0.0, -0.0, 1.0, -1.0, 1.5, -1.5,
123.456789, -123.456789, 1.0E10, 1.0E-10,
Double.MAX_VALUE, Double.MIN_VALUE, Double.MIN_NORMAL,
Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY
};
for (double v : values) {
_verifyDouble(v);
}
}
@Test
public void testWriteRandom()
{
Random rnd = new Random(2468);
for (int i = 0; i < 10_000; ++i) {
_verifyFloat(Float.intBitsToFloat(rnd.nextInt()));
_verifyDouble(Double.longBitsToDouble(rnd.nextLong()));
}
}
@Test
public void testWriteFloatAtOffset()
{
char[] buf = new char[32];
buf[0] = ',';
int end = NumberOutput.outputFloat(1.5f, buf, 1);
assertEquals("1.5", new String(buf, 1, end - 1));
assertEquals(',', buf[0]);
}
@Test
public void testWriteDoubleAtOffset()
{
char[] buf = new char[48];
buf[0] = ',';
int end = NumberOutput.outputDouble(1.5, buf, 1);
assertEquals("1.5", new String(buf, 1, end - 1));
assertEquals(',', buf[0]);
}
@Test
public void testMaxLengthFitsInBuffer()
{
// Longest forms: exactly MAX_*_BYTES chars, must not overflow a tight buffer
char[] buf = new char[NumberOutput.MAX_DOUBLE_BYTES];
int end = NumberOutput.outputDouble(-Double.MIN_NORMAL, buf, 0);
assertTrue(end <= NumberOutput.MAX_DOUBLE_BYTES);
assertEquals(NumberOutput.toString(-Double.MIN_NORMAL, true), new String(buf, 0, end));
buf = new char[NumberOutput.MAX_FLOAT_BYTES];
end = NumberOutput.outputFloat(-Float.MIN_NORMAL, buf, 0);
assertTrue(end <= NumberOutput.MAX_FLOAT_BYTES);
assertEquals(NumberOutput.toString(-Float.MIN_NORMAL, true), new String(buf, 0, end));
}
private void _verifyFloat(float v)
{
String expected = NumberOutput.toString(v, true);
char[] buf = new char[32];
int end = NumberOutput.outputFloat(v, buf, 0);
assertEquals(expected, new String(buf, 0, end), "mismatch for float " + v);
// and must agree with the byte[] variant
byte[] bbuf = new byte[32];
int bend = NumberOutput.outputFloat(v, bbuf, 0);
assertEquals(expected, new String(bbuf, 0, bend, StandardCharsets.US_ASCII),
"byte[] mismatch for float " + v);
}
private void _verifyDouble(double v)
{
String expected = NumberOutput.toString(v, true);
char[] buf = new char[48];
int end = NumberOutput.outputDouble(v, buf, 0);
assertEquals(expected, new String(buf, 0, end), "mismatch for double " + v);
byte[] bbuf = new byte[48];
int bend = NumberOutput.outputDouble(v, bbuf, 0);
assertEquals(expected, new String(bbuf, 0, bend, StandardCharsets.US_ASCII),
"byte[] mismatch for double " + v);
}
}