Skip to content

Commit

Permalink
allowing custom float overflow handling
Browse files Browse the repository at this point in the history
  • Loading branch information
lucianoviana committed Jan 17, 2025
1 parent 7f1998c commit 907e5ce
Show file tree
Hide file tree
Showing 15 changed files with 648 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import uk.co.real_logic.artio.fields.DecimalFloat;
import uk.co.real_logic.artio.util.AsciiBuffer;
import uk.co.real_logic.artio.util.float_parsing.DecimalFloatOverflowHandler;

import static uk.co.real_logic.artio.dictionary.generation.CodecUtil.MISSING_INT;
import static uk.co.real_logic.artio.dictionary.generation.CodecUtil.MISSING_LONG;
Expand All @@ -31,6 +32,7 @@ public abstract class CommonDecoderImpl
protected int invalidTagId = Decoder.NO_ERROR;
protected int rejectReason = Decoder.NO_ERROR;
protected AsciiBuffer buffer;
protected DecimalFloatOverflowHandler decimalFloatOverflowHandler;

public int invalidTagId()
{
Expand Down Expand Up @@ -82,11 +84,12 @@ public long getLong(

public DecimalFloat getFloat(
final AsciiBuffer buffer,
final DecimalFloat number, final int offset, final int length, final int tag, final boolean validation)
final DecimalFloat number, final int offset, final int length, final int tag, final boolean validation,
final DecimalFloatOverflowHandler decimalFloatOverflowHandler)
{
try
{
return buffer.getFloat(number, offset, length);
return buffer.getFloat(number, offset, length, tag, decimalFloatOverflowHandler);
}
catch (final NumberFormatException | ArithmeticException e)
{
Expand All @@ -104,6 +107,14 @@ public DecimalFloat getFloat(
}
}

public DecimalFloat getFloat(
final AsciiBuffer buffer,
final DecimalFloat number, final int offset, final int length, final int tag, final boolean validation)
{
return getFloat(buffer, number, offset, length, tag, validation, null);
}


public int getIntFlyweight(
final AsciiBuffer buffer, final int offset, final int length, final int tag, final boolean validation)
{
Expand Down Expand Up @@ -168,11 +179,12 @@ public DecimalFloat getFloatFlyweight(
final int offset,
final int length,
final int tag,
final boolean codecValidationEnabled)
final boolean codecValidationEnabled,
final DecimalFloatOverflowHandler decimalFloatOverflowHandler)
{
try
{
return buffer.getFloat(number, offset, length);
return buffer.getFloat(number, offset, length, tag, decimalFloatOverflowHandler);
}
catch (final NumberFormatException e)
{
Expand All @@ -187,4 +199,15 @@ public DecimalFloat getFloatFlyweight(
}
}
}

public DecimalFloat getFloatFlyweight(
final AsciiBuffer buffer,
final DecimalFloat number,
final int offset,
final int length,
final int tag,
final boolean codecValidationEnabled)
{
return getFloatFlyweight(buffer, number, offset, length, tag, codecValidationEnabled, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.io.InputStream;
import java.util.function.BiFunction;

import uk.co.real_logic.artio.util.float_parsing.DecimalFloatOverflowHandler;

public final class CodecConfiguration
{
/**
Expand Down Expand Up @@ -55,6 +57,7 @@ public final class CodecConfiguration
public static final String PARENT_PACKAGE_PROPERTY = "fix.codecs.parent_package";
public static final String FLYWEIGHTS_ENABLED_PROPERTY = "fix.codecs.flyweight";
public static final String REJECT_UNKNOWN_ENUM_VALUE_PROPERTY = "reject.unknown.enum.value";
public static final String FLOAT_OVERFLOW_HANDLER_PROPERTY = "float.overflow.handler";
public static final String FIX_TAGS_IN_JAVADOC = "fix.codecs.tags_in_javadoc";

public static final String DEFAULT_PARENT_PACKAGE = "uk.co.real_logic.artio";
Expand All @@ -74,6 +77,7 @@ public final class CodecConfiguration
private final GeneratorDictionaryConfiguration nonSharedDictionary =
new GeneratorDictionaryConfiguration(null, null, null,
Boolean.getBoolean(FIX_CODECS_ALLOW_DUPLICATE_FIELDS_PROPERTY));
private Class<? extends DecimalFloatOverflowHandler> decimalFloatOverflowHandler = null;

public CodecConfiguration()
{
Expand All @@ -94,6 +98,18 @@ public CodecConfiguration outputPath(final String outputPath)
return this;
}

public CodecConfiguration decimalFloatOverflowHandler(
final Class<? extends DecimalFloatOverflowHandler> decimalFloatOverflowHandler)
{
this.decimalFloatOverflowHandler = decimalFloatOverflowHandler;
return this;
}

public Class<? extends DecimalFloatOverflowHandler> getDecimalFloatOverflowHandler()
{
return decimalFloatOverflowHandler;
}

/**
* Sets the parent package where classes are generated. Optional, defaults to {@link #DEFAULT_PARENT_PACKAGE}.
* Different parent packages can be used to use multiple different fix dictionary versions, see the
Expand Down Expand Up @@ -305,5 +321,24 @@ void conclude()
"Please provide a path to the XML files either through the fileNames() or fileStreams() option.");
}
}
if (decimalFloatOverflowHandler == null)
{

final String floatOverflowHandler = System.getProperty(FLOAT_OVERFLOW_HANDLER_PROPERTY);
if (floatOverflowHandler != null)
{
try
{
//noinspection unchecked
decimalFloatOverflowHandler = (Class<? extends DecimalFloatOverflowHandler>)Class.forName(
floatOverflowHandler);
}
catch (final ClassNotFoundException e)
{
throw new IllegalArgumentException("Unable to load DecimalFloatOverflowHandler: " +
floatOverflowHandler, e);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ private static void generateDictionary(
false,
configuration.wrapEmptyBuffer(),
codecRejectUnknownEnumValueEnabled,
configuration.fixTagsInJavadoc()).generate();
configuration.fixTagsInJavadoc(),
configuration.getDecimalFloatOverflowHandler()).generate();

new PrinterGenerator(dictionary, decoderPackage, decoderOutput).generate();
new AcceptorGenerator(dictionary, decoderPackage, decoderOutput).generate();
Expand All @@ -203,7 +204,8 @@ private static void generateDictionary(
true,
configuration.wrapEmptyBuffer(),
codecRejectUnknownEnumValueEnabled,
configuration.fixTagsInJavadoc()).generate();
configuration.fixTagsInJavadoc(),
configuration.getDecimalFloatOverflowHandler()).generate();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import uk.co.real_logic.artio.dictionary.ir.Field.Type;
import uk.co.real_logic.artio.fields.*;
import uk.co.real_logic.artio.util.MessageTypeEncoding;
import uk.co.real_logic.artio.util.float_parsing.DecimalFloatOverflowHandler;

import java.io.IOException;
import java.io.Writer;
Expand Down Expand Up @@ -134,9 +135,42 @@ static String decoderClassName(final String name)
final boolean wrapEmptyBuffer,
final String codecRejectUnknownEnumValueEnabled,
final boolean fixTagsInJavadoc)
{
this(dictionary,
initialBufferSize,
thisPackage,
commonPackage,
encoderPackage,
outputManager,
validationClass,
rejectUnknownFieldClass,
rejectUnknownEnumValueClass,
flyweightsEnabled,
wrapEmptyBuffer,
codecRejectUnknownEnumValueEnabled,
fixTagsInJavadoc,
null);
}

DecoderGenerator(
final Dictionary dictionary,
final int initialBufferSize,
final String thisPackage,
final String commonPackage,
final String encoderPackage,
final OutputManager outputManager,
final Class<?> validationClass,
final Class<?> rejectUnknownFieldClass,
final Class<?> rejectUnknownEnumValueClass,
final boolean flyweightsEnabled,
final boolean wrapEmptyBuffer,
final String codecRejectUnknownEnumValueEnabled,
final boolean fixTagsInJavadoc,
final Class<? extends DecimalFloatOverflowHandler> decimalFloatOverflowHandler)
{
super(dictionary, thisPackage, commonPackage, outputManager, validationClass, rejectUnknownFieldClass,
rejectUnknownEnumValueClass, flyweightsEnabled, codecRejectUnknownEnumValueEnabled, fixTagsInJavadoc);
rejectUnknownEnumValueClass, flyweightsEnabled, codecRejectUnknownEnumValueEnabled, fixTagsInJavadoc,
decimalFloatOverflowHandler);
this.initialBufferSize = initialBufferSize;
this.encoderPackage = encoderPackage;
this.wrapEmptyBuffer = wrapEmptyBuffer;
Expand Down Expand Up @@ -192,6 +226,11 @@ else if (type == HEADER)

importEncoders(aggregate, out);

if (decimalFloatOverflowHandler != null)
{
out.append(importFor(decimalFloatOverflowHandler));
}

generateAggregateClass(aggregate, type, className, out);
});
}
Expand Down Expand Up @@ -255,6 +294,13 @@ else if (type == HEADER)
}

out.append(classDeclaration(className, interfaces, false, aggregate.isInParent(), isGroup));
if (decimalFloatOverflowHandler != null && type != HEADER)
{
out.append(String.format(" public %s() {\n\n", className));
out.append(String.format(" decimalFloatOverflowHandler = new %s",
decimalFloatOverflowHandler.getSimpleName() + "();\n\n"));
out.append(" }\n\n");
}
generateValidation(out, aggregate, type);
if (isMessage)
{
Expand Down Expand Up @@ -2041,7 +2087,8 @@ private String fieldDecodeMethod(final Field field, final String fieldName)
return "";
}
decodeMethod = String.format(
"getFloat(buffer, %s, valueOffset, valueLength, %d, " + CODEC_VALIDATION_ENABLED + ")",
"getFloat(buffer, %s, valueOffset, valueLength, %d, " + CODEC_VALIDATION_ENABLED +
", decimalFloatOverflowHandler)",
fieldName, field.number());
break;
case CHAR:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ static String encoderClassName(final String name)
final boolean fixTagsInJavadoc)
{
super(dictionary, builderPackage, builderCommonPackage, outputManager, validationClass, rejectUnknownFieldClass,
rejectUnknownEnumValueClass, false, codecRejectUnknownEnumValueEnabled, fixTagsInJavadoc);
rejectUnknownEnumValueClass, false, codecRejectUnknownEnumValueEnabled, fixTagsInJavadoc, null);

final Component header = dictionary.header();
validateHasField(header, BEGIN_STRING);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import uk.co.real_logic.artio.fields.UtcTimestampEncoder;
import uk.co.real_logic.artio.util.AsciiBuffer;
import uk.co.real_logic.artio.util.MutableAsciiBuffer;
import uk.co.real_logic.artio.util.float_parsing.DecimalFloatOverflowHandler;

import java.io.IOException;
import java.io.Writer;
Expand Down Expand Up @@ -97,6 +98,7 @@ protected String commonCompoundImports(final String form, final boolean headerWr
protected final boolean flyweightsEnabled;
protected final String codecRejectUnknownEnumValueEnabled;
protected final String scope;
protected final Class<? extends DecimalFloatOverflowHandler> decimalFloatOverflowHandler;
protected final boolean fixTagsInJavadoc;

protected final Deque<Aggregate> aggregateStack = new ArrayDeque<>();
Expand All @@ -111,7 +113,8 @@ protected Generator(
final Class<?> rejectUnknownEnumValueClass,
final boolean flyweightsEnabled,
final String codecRejectUnknownEnumValueEnabled,
final boolean fixTagsInJavadoc)
final boolean fixTagsInJavadoc,
final Class<? extends DecimalFloatOverflowHandler> decimalFloatOverflowHandler)
{
this.dictionary = dictionary;
this.thisPackage = thisPackage;
Expand All @@ -125,6 +128,7 @@ protected Generator(
this.fixTagsInJavadoc = fixTagsInJavadoc;

scope = dictionary.shared() ? "protected" : "private";
this.decimalFloatOverflowHandler = decimalFloatOverflowHandler;
}

public void generate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.agrona.DirectBuffer;
import uk.co.real_logic.artio.fields.DecimalFloat;
import uk.co.real_logic.artio.util.float_parsing.DecimalFloatOverflowHandler;

/**
* Mutable String class that flyweights a data buffer. This assumes a US-ASCII encoding
Expand Down Expand Up @@ -67,7 +68,18 @@ public interface AsciiBuffer extends DirectBuffer

long getMessageType(int offset, int length);

DecimalFloat getFloat(DecimalFloat number, int offset, int length);
DecimalFloat getFloat(DecimalFloat number,
int offset,
int length,
int tagId,
DecimalFloatOverflowHandler decimalFloatOverflowHandler);

default DecimalFloat getFloat(DecimalFloat number,
int offset,
int length)
{
return getFloat(number, offset, length, -1, null);
}

int getLocalMktDate(int offset, int length);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.agrona.concurrent.UnsafeBuffer;
import uk.co.real_logic.artio.fields.*;
import uk.co.real_logic.artio.util.float_parsing.AsciiBufferCharReader;
import uk.co.real_logic.artio.util.float_parsing.DecimalFloatOverflowHandler;
import uk.co.real_logic.artio.util.float_parsing.DecimalFloatParser;

import java.nio.ByteBuffer;
Expand Down Expand Up @@ -167,9 +168,19 @@ public long getMessageType(final int offset, final int length)
}

@SuppressWarnings("FinalParameters")
public DecimalFloat getFloat(final DecimalFloat number, int offset, int length)
{
return DecimalFloatParser.extract(number, AsciiBufferCharReader.INSTANCE, this, offset, length);
public DecimalFloat getFloat(final DecimalFloat number,
int offset,
int length,
int tagId,
DecimalFloatOverflowHandler decimalFloatOverflowHandler)
{
return DecimalFloatParser.extract(number,
AsciiBufferCharReader.INSTANCE,
this,
offset,
length,
tagId,
decimalFloatOverflowHandler);
}

public int getLocalMktDate(final int offset, final int length)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2015-2025 Real Logic Limited.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.co.real_logic.artio.util.float_parsing;

import uk.co.real_logic.artio.fields.DecimalFloat;

public interface DecimalFloatOverflowHandler
{
DecimalFloat handleOverflow(CharSequence valueWithOverflow,
int positionOfOverflow,
int positionOfDecimalPoint,
int tagId);
}
Loading

0 comments on commit 907e5ce

Please sign in to comment.