diff --git a/quickfixj-core/src/main/java/quickfix/FieldMap.java b/quickfixj-core/src/main/java/quickfix/FieldMap.java index 6f5c9ef272..d78bf5cf2f 100644 --- a/quickfixj-core/src/main/java/quickfix/FieldMap.java +++ b/quickfixj-core/src/main/java/quickfix/FieldMap.java @@ -31,6 +31,7 @@ import quickfix.field.converter.UtcDateOnlyConverter; import quickfix.field.converter.UtcTimeOnlyConverter; import quickfix.field.converter.UtcTimestampConverter; +import org.quickfixj.CharsetSupport; import java.io.Serializable; import java.math.BigDecimal; @@ -471,8 +472,9 @@ protected void calculateString(StringBuilder buffer, int[] preFields, int[] post } else if (isGroupField(tag) && isOrderedField(tag, fieldOrder) && getGroupCount(tag) > 0) { appendField(buffer, field); - for (Group group : getGroups(tag)) { - group.calculateString(buffer, preFields, postFields); + List groups = getGroups(tag); + for (int i = 0; i < groups.size(); i++) { + groups.get(i).calculateString(buffer, preFields, postFields); } } } @@ -483,10 +485,10 @@ && getGroupCount(tag) > 0) { final List groups = entry.getValue(); int groupCount = groups.size(); if (groupCount > 0) { - final IntField countField = new IntField(groupCountTag.intValue(), groupCount); - appendField(buffer, countField); - for (Group group : groups) { - group.calculateString(buffer, preFields, postFields); + buffer.append(NumbersCache.get(groupCountTag)).append('='); + buffer.append(NumbersCache.get(groupCount)).append('\001'); + for (int i = 0; i < groups.size(); i++) { + groups.get(i).calculateString(buffer, preFields, postFields); } } } @@ -499,6 +501,8 @@ && getGroupCount(tag) > 0) { } } + private static final boolean IS_STRING_EQUIVALENT = CharsetSupport.isStringEquivalent(CharsetSupport.getCharsetInstance()); + int calculateLength() { int result = 0; for (final Field field : fields.values()) { @@ -512,17 +516,27 @@ int calculateLength() { for (Entry> entry : groups.entrySet()) { final List groupList = entry.getValue(); if (!groupList.isEmpty()) { - final IntField groupField = new IntField(entry.getKey()); - groupField.setValue(groupList.size()); - result += groupField.getLength(); - for (final Group group : groupList) { - result += group.calculateLength(); + if(IS_STRING_EQUIVALENT) { + result += getStringLength(entry.getKey()) + getStringLength(groupList.size()) + 2; + } else { + result += MessageUtils.length(CharsetSupport.getCharsetInstance(), NumbersCache.get(entry.getKey())); + result += MessageUtils.length(CharsetSupport.getCharsetInstance(), NumbersCache.get(groupList.size())); + result += 2; + } + for (int i = 0; i < groupList.size(); i++) { + result += groupList.get(i).calculateLength(); } } } return result; } + private static int getStringLength(int num) { + if(num == 0) + return 1; + return (int)(num > 0 ? Math.log10(num) + 1 : Math.log10(-num) + 2); + } + int calculateChecksum() { int result = 0; for (final Field field : fields.values()) { @@ -534,11 +548,21 @@ int calculateChecksum() { for (Entry> entry : groups.entrySet()) { final List groupList = entry.getValue(); if (!groupList.isEmpty()) { - final IntField groupField = new IntField(entry.getKey()); - groupField.setValue(groupList.size()); - result += groupField.getChecksum(); - for (final Group group : groupList) { - result += group.calculateChecksum(); + if(IS_STRING_EQUIVALENT) { + String value = NumbersCache.get(entry.getKey()); + for (int i = value.length(); i-- != 0;) + result += value.charAt(i); + value = NumbersCache.get(groupList.size()); + for (int i = value.length(); i-- != 0;) + result += value.charAt(i); + result += '=' + 1; + } else { + final IntField groupField = new IntField(entry.getKey()); + groupField.setValue(groupList.size()); + result += groupField.getChecksum(); + } + for (int i = 0; i < groupList.size(); i++) { + result += groupList.get(i).calculateChecksum(); } } } @@ -662,4 +686,5 @@ public boolean hasGroup(Group group) { return hasGroup(group.getFieldTag()); } + } diff --git a/quickfixj-core/src/main/java/quickfix/NumbersCache.java b/quickfixj-core/src/main/java/quickfix/NumbersCache.java index 1a3725884a..fdacaa695b 100644 --- a/quickfixj-core/src/main/java/quickfix/NumbersCache.java +++ b/quickfixj-core/src/main/java/quickfix/NumbersCache.java @@ -48,16 +48,18 @@ public static String get(int i) { return String.valueOf(i); } - /** - * Get the string representing the given double if it's an integer - * - * @param d the double to convert - * @return the String representing the double or null if the double is not an integer - */ + + /** + * Get the string representing the given double if it's an integer + * + * @param d the double to convert + * @return the String representing the double or null if the double is not an integer + */ public static String get(double d) { long l = (long)d; if (d == (double)l) return get(l); return null; - } + } + }