Skip to content
Richard Warburton edited this page Nov 23, 2018 · 12 revisions

Codec Generation

If you want to use the encoders and decoders from Artio in order to parse or generate FIX then you should use the CodecGenerationTool. It takes two arguments. The first is the output directory, and the second is the path to the XML dictionary to use to define the variant in use.

Commandline Example

java -cp "fix-gateway-samples/build/libs/artio-samples.jar-${ARTIO-VERSION}-all.jar" \
uk.co.real_logic.artio.dictionary.CodecGenerationTool  \
/path/to/generated-src/directory \ 
src/main/resources/your_fix_dictionary_file.xml

Maven Example

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>java</goal>
            </goals>
            <phase>generate-sources</phase>
        </execution>
    </executions>

    <configuration>
        <mainClass>uk.co.real_logic.artio.dictionary.CodecGenerationTool</mainClass>
        <arguments>
            <argument>${project.build.directory}/generated-sources/java</argument>
            <argument>src/main/resources/your_fix_dictionary_file.xml</argument>
        </arguments>
    </configuration>
</plugin>

Gradle Example

task generateCodecs(type: JavaExec) {
    main = 'uk.co.real_logic.artio.dictionary.CodecGenerationTool'
    classpath = sourceSets.main.runtimeClasspath
    args = ['/path/to/generated-src/directory', 'src/main/resources/your_fix_dictionary_file.xml']
    outputs.dir '/path/to/generated-src/directory'
}

Codec Usage

The generated Codecs are objects that are designed to be re-used over multiple messages in order to minimise the amount of garbage generated during steady-state usage.

String-like FIX types

The decoders parse into internal buffers that are re-used over multiple parses. If the input data is longer than the existing buffer size then the buffer will grow. Allocation only happens when you grow the buffer. Since messages never have infinitely increasing message sizes you will eventually hit the max size of the buffer.

Internally for parsing String values we convert into a char[] and length for the field. This means that if you retrieve the char[] value you always need to be aware that it is only the first length number of characters that are relevant values. There is also an easy AsString variant of each method that will allocate you a String if you prefer an easier programming model and are less latency sensitive.

Each of the generated methods follows a common naming scheme, to take the String username field of a LogonDecoder as an example:

  • username() - The char[] value getter.
  • usernameLength() - The int getter for the length of the char[] value.
  • usernameAsString() - The higher overhead, but easier to use variant that returns java.lang.String values.

Validation

Codec validation can be switched on or off at runtime by setting the Java system property fix.codecs.no_validation to either true or false. Validation checks syntactic issues around FIX messages. For example:

  • Whether they only contain fields that are defined for that message.
  • Whether all the required fields are present.
  • Whether enum types only contain valid values.

In order to validate a FIX message that you have received and parsed, call validate() on your decoder. Its boolean return value denotes whether the message is valid or not. If it's invalid then you can call decoder.invalidTagId() to see which tag caused the validation to fail and decoder.rejectReason() to see the reason why it failed.

Resets

If you've received a message and plan to parse another message then you should call reset() on the decoder to ensure that no fields that were set from the previous message are still in use.

Clone this wiki locally