uk.co.real_logic.sbe.generation.csharp.CSharpUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sbe-all Show documentation
Show all versions of sbe-all Show documentation
FIX/SBE - OSI layer 6 presentation for encoding and decoding application messages in binary format for low-latency applications.
/*
* Copyright 2013-2024 Real Logic Limited.
* Copyright (C) 2017 MarketFactory, Inc
*
* 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.sbe.generation.csharp;
import uk.co.real_logic.sbe.PrimitiveType;
import uk.co.real_logic.sbe.SbeTool;
import uk.co.real_logic.sbe.ValidationUtil;
import uk.co.real_logic.sbe.generation.Generators;
import uk.co.real_logic.sbe.ir.Token;
import java.util.EnumMap;
import java.util.Map;
/**
* Utilities for mapping between IR and the C# language.
*/
public class CSharpUtil
{
static String generateLiteral(final PrimitiveType type, final String value)
{
String literal = "";
final String castType = cSharpTypeName(type);
switch (type)
{
case CHAR:
case UINT8:
case INT8:
case INT16:
case UINT16:
literal = "(" + castType + ")" + value;
break;
case INT32:
literal = value;
break;
case UINT32:
literal = value + "U";
break;
case FLOAT:
if (value.endsWith("NaN"))
{
literal = "float.NaN";
}
else
{
literal = value + "f";
}
break;
case UINT64:
literal = "0x" + Long.toHexString(Long.parseLong(value)) + "UL";
break;
case INT64:
literal = value + "L";
break;
case DOUBLE:
if (value.endsWith("NaN"))
{
literal = "double.NaN";
}
else
{
literal = value + "d";
}
break;
}
return literal;
}
static CharSequence generateFileHeader(final String packageName, final String... topLevelStatements)
{
return String.format(
"// \n" +
"// Generated SBE (Simple Binary Encoding) message codec\n" +
"// \n\n" +
"#pragma warning disable 1591 // disable warning on missing comments\n" +
"%1$s" +
"using System;\n" +
"using System.Text;\n" +
"using Org.SbeTool.Sbe.Dll;\n\n" +
"namespace %2$s\n" +
"{\n",
String.join("", topLevelStatements),
formatNamespace(packageName));
}
static String formatNamespace(final String packageName)
{
String[] tokens = packageName.split("\\.");
final StringBuilder sb = new StringBuilder();
for (final String t : tokens)
{
sb.append(Generators.toUpperFirstChar(t)).append(".");
}
if (sb.length() > 0)
{
sb.setLength(sb.length() - 1);
}
tokens = sb.toString().split("-");
sb.setLength(0);
for (final String t : tokens)
{
sb.append(Generators.toUpperFirstChar(t));
}
return sb.toString();
}
static String generateDocumentation(final String indent, final Token token)
{
final String description = token.description();
if (null == description || description.isEmpty())
{
return "";
}
return
indent + "/// \n" +
indent + "/// " + description + "\n" +
indent + "/// \n";
}
enum Separators
{
BEGIN_GROUP('['),
END_GROUP(']'),
BEGIN_COMPOSITE('('),
END_COMPOSITE(')'),
BEGIN_SET('{'),
END_SET('}'),
BEGIN_ARRAY('['),
END_ARRAY(']'),
FIELD('|'),
KEY_VALUE('='),
ENTRY(',');
private final char symbol;
Separators(final char symbol)
{
this.symbol = symbol;
}
void appendToGeneratedBuilder(final StringBuilder builder, final String indent)
{
builder.append(indent).append("builder.Append('").append(symbol).append("');").append('\n');
}
/**
* Returns the string value of this separator.
*
* @return the string value of this separator
*/
public String toString()
{
return String.valueOf(symbol);
}
}
private static final Map PRIMITIVE_TYPE_STRING_ENUM_MAP = new EnumMap<>(PrimitiveType.class);
/*
* http://msdn.microsoft.com/en-us/library/ms228360(v=vs.90).aspx
*/
static
{
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.CHAR, "byte");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.INT8, "sbyte");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.INT16, "short");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.INT32, "int");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.INT64, "long");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.UINT8, "byte");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.UINT16, "ushort");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.UINT32, "uint");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.UINT64, "ulong");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.FLOAT, "float");
PRIMITIVE_TYPE_STRING_ENUM_MAP.put(PrimitiveType.DOUBLE, "double");
}
/**
* Map the name of a {@link uk.co.real_logic.sbe.PrimitiveType} to a C# primitive type name.
*
* @param primitiveType to map.
* @return the name of the Java primitive that most closely maps.
*/
static String cSharpTypeName(final PrimitiveType primitiveType)
{
return PRIMITIVE_TYPE_STRING_ENUM_MAP.get(primitiveType);
}
/**
* Uppercase the first character of a given String.
*
* @param str to have the first character upper-cased.
* @return a new String with the first character in uppercase.
*/
public static String toUpperFirstChar(final String str)
{
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
/**
* Lowercase the first character of a given String.
*
* @param str to have the first character upper-cased.
* @return a new String with the first character in uppercase.
*/
public static String toLowerFirstChar(final String str)
{
return Character.toLowerCase(str.charAt(0)) + str.substring(1);
}
/**
* Format a String as a property name.
*
* @param str to be formatted.
* @return the string formatted as a property name.
*/
public static String formatPropertyName(final String str)
{
return toUpperFirstChar(str);
}
/**
* Format a String with a suffix in case it's a keyword.
*
* @param value to be formatted.
* @return the formatted string.
*/
public static String formatForCSharpKeyword(final String value)
{
if (ValidationUtil.isCSharpKeyword(value))
{
final String keywordAppendToken = System.getProperty(SbeTool.KEYWORD_APPEND_TOKEN);
if (null == keywordAppendToken)
{
throw new IllegalStateException(
"Invalid property name='" + value +
"' please correct the schema or consider setting system property: " + SbeTool.KEYWORD_APPEND_TOKEN);
}
return value + keywordAppendToken;
}
return value;
}
/**
* Format a String as a variable name.
*
* @param str to be formatted.
* @return the string formatted as a property name.
*/
public static String formatVariableName(final String str)
{
return toLowerFirstChar(str);
}
/**
* Format a String as a class name.
*
* @param str to be formatted.
* @return the string formatted as a class name.
*/
public static String formatClassName(final String str)
{
return toUpperFirstChar(str);
}
/**
* Format a Getter name for generated code.
*
* @param propertyName to be formatted.
* @return the property name formatted as a getter name.
*/
public static String formatGetterName(final String propertyName)
{
return "Get" + toUpperFirstChar(propertyName);
}
/**
* Shortcut to append a line of generated code
*
* @param builder string builder to which to append the line
* @param indent current text indentation
* @param line line to be appended
*/
public static void append(final StringBuilder builder, final String indent, final String line)
{
builder.append(indent).append(line).append('\n');
}
}