Skip to content

Commit cbb9567

Browse files
committed
[Java] Improve iteration over tokens in stub generation for Java and C++.
1 parent c1cbdf7 commit cbb9567

File tree

2 files changed

+182
-170
lines changed

2 files changed

+182
-170
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/cpp/CppGenerator.java

Lines changed: 127 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ public void generate() throws IOException
142142

143143
final StringBuilder sb = new StringBuilder();
144144
out.append(generateFields(className, fields, BASE_INDENT));
145-
generateGroups(sb, groups, 0, BASE_INDENT);
145+
generateGroups(sb, groups, BASE_INDENT);
146146
out.append(sb);
147147
out.append(generateVarData(className, varData, BASE_INDENT));
148148

@@ -151,40 +151,40 @@ public void generate() throws IOException
151151
}
152152
}
153153

154-
private int generateGroups(final StringBuilder sb, final List<Token> tokens, int index, final String indent)
154+
private void generateGroups(final StringBuilder sb, final List<Token> tokens, final String indent)
155155
{
156-
for (int size = tokens.size(); index < size; index++)
156+
for (int i = 0, size = tokens.size(); i < size; i++)
157157
{
158-
if (tokens.get(index).signal() == Signal.BEGIN_GROUP)
158+
final Token groupToken = tokens.get(i);
159+
if (groupToken.signal() != Signal.BEGIN_GROUP)
159160
{
160-
final Token groupToken = tokens.get(index);
161-
final String groupName = groupToken.name();
162-
final String cppTypeForNumInGroup = cppTypeName(tokens.get(index + 3).encoding().primitiveType());
161+
throw new IllegalStateException("tokens must begin with BEGIN_GROUP: token=" + groupToken);
162+
}
163163

164-
generateGroupClassHeader(sb, groupName, tokens, index, indent + INDENT);
164+
final String groupName = groupToken.name();
165+
final String cppTypeForNumInGroup = cppTypeName(tokens.get(i + 3).encoding().primitiveType());
165166

166-
++index;
167-
final int groupHeaderTokenCount = tokens.get(index).componentTokenCount();
168-
index += groupHeaderTokenCount;
167+
generateGroupClassHeader(sb, groupName, tokens, i, indent + INDENT);
169168

170-
final List<Token> fields = new ArrayList<>();
171-
index = collectFields(tokens, index, fields);
172-
sb.append(generateFields(groupName, fields, indent + INDENT));
169+
++i;
170+
final int groupHeaderTokenCount = tokens.get(i).componentTokenCount();
171+
i += groupHeaderTokenCount;
173172

174-
final List<Token> groups = new ArrayList<>();
175-
index = collectGroups(tokens, index, groups);
176-
generateGroups(sb, groups, 0, indent + INDENT);
173+
final List<Token> fields = new ArrayList<>();
174+
i = collectFields(tokens, i, fields);
175+
sb.append(generateFields(groupName, fields, indent + INDENT));
177176

178-
final List<Token> varData = new ArrayList<>();
179-
collectVarData(tokens, index, varData);
180-
sb.append(generateVarData(formatClassName(groupName), varData, indent + INDENT));
177+
final List<Token> groups = new ArrayList<>();
178+
i = collectGroups(tokens, i, groups);
179+
generateGroups(sb, groups, indent + INDENT);
181180

182-
sb.append(indent).append(" };\n");
183-
sb.append(generateGroupProperty(groupName, groupToken, cppTypeForNumInGroup, indent));
184-
}
185-
}
181+
final List<Token> varData = new ArrayList<>();
182+
collectVarData(tokens, i, varData);
183+
sb.append(generateVarData(formatClassName(groupName), varData, indent + INDENT));
186184

187-
return index;
185+
sb.append(indent).append(" };\n");
186+
sb.append(generateGroupProperty(groupName, groupToken, cppTypeForNumInGroup, indent));
187+
}
188188
}
189189

190190
private void generateGroupClassHeader(
@@ -374,114 +374,118 @@ private CharSequence generateVarData(final String className, final List<Token> t
374374
{
375375
final StringBuilder sb = new StringBuilder();
376376

377-
for (int i = 0, size = tokens.size(); i < size; i++)
377+
for (int i = 0, size = tokens.size(); i < size;)
378378
{
379379
final Token token = tokens.get(i);
380-
if (token.signal() == Signal.BEGIN_VAR_DATA)
380+
if (token.signal() != Signal.BEGIN_VAR_DATA)
381381
{
382-
final String propertyName = toUpperFirstChar(token.name());
383-
final String characterEncoding = tokens.get(i + 3).encoding().characterEncoding();
384-
final Token lengthToken = tokens.get(i + 2);
385-
final int lengthOfLengthField = lengthToken.encodedLength();
386-
final String lengthCppType = cppTypeName(lengthToken.encoding().primitiveType());
382+
throw new IllegalStateException("tokens must begin with BEGIN_VAR_DATA: token=" + token);
383+
}
387384

388-
generateFieldMetaAttributeMethod(sb, token, indent);
385+
final String propertyName = toUpperFirstChar(token.name());
386+
final String characterEncoding = tokens.get(i + 3).encoding().characterEncoding();
387+
final Token lengthToken = tokens.get(i + 2);
388+
final int lengthOfLengthField = lengthToken.encodedLength();
389+
final String lengthCppType = cppTypeName(lengthToken.encoding().primitiveType());
389390

390-
generateVarDataDescriptors(
391-
sb, token, propertyName, characterEncoding, lengthToken, lengthOfLengthField, lengthCppType, indent);
391+
generateFieldMetaAttributeMethod(sb, token, indent);
392392

393-
sb.append(String.format(
394-
indent + " const char *%1$s(void)\n" +
395-
indent + " {\n" +
396-
"%2$s" +
397-
indent + " const char *fieldPtr = (m_buffer + position() + %3$d);\n" +
398-
indent + " position(position() + %3$d + *((%4$s *)(m_buffer + position())));\n" +
399-
indent + " return fieldPtr;\n" +
400-
indent + " }\n\n",
401-
formatPropertyName(propertyName),
402-
generateTypeFieldNotPresentCondition(token.version(), BASE_INDENT),
403-
lengthOfLengthField,
404-
lengthCppType
405-
));
393+
generateVarDataDescriptors(
394+
sb, token, propertyName, characterEncoding, lengthToken, lengthOfLengthField, lengthCppType, indent);
406395

407-
sb.append(String.format(
408-
indent + " std::uint64_t get%1$s(char *dst, const std::uint64_t length)\n" +
409-
indent + " {\n" +
410-
"%2$s" +
411-
indent + " std::uint64_t lengthOfLengthField = %3$d;\n" +
412-
indent + " std::uint64_t lengthPosition = position();\n" +
413-
indent + " position(lengthPosition + lengthOfLengthField);\n" +
414-
indent + " std::uint64_t dataLength = %4$s(*((%5$s *)(m_buffer + lengthPosition)));\n" +
415-
indent + " std::uint64_t bytesToCopy = (length < dataLength) ? length : dataLength;\n" +
416-
indent + " std::uint64_t pos = position();\n" +
417-
indent + " position(position() + dataLength);\n" +
418-
indent + " std::memcpy(dst, m_buffer + pos, bytesToCopy);\n" +
419-
indent + " return bytesToCopy;\n" +
420-
indent + " }\n\n",
421-
propertyName,
422-
generateArrayFieldNotPresentCondition(token.version(), BASE_INDENT),
423-
lengthOfLengthField,
424-
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType()),
425-
lengthCppType
426-
));
396+
sb.append(String.format(
397+
indent + " const char *%1$s(void)\n" +
398+
indent + " {\n" +
399+
"%2$s" +
400+
indent + " const char *fieldPtr = (m_buffer + position() + %3$d);\n" +
401+
indent + " position(position() + %3$d + *((%4$s *)(m_buffer + position())));\n" +
402+
indent + " return fieldPtr;\n" +
403+
indent + " }\n\n",
404+
formatPropertyName(propertyName),
405+
generateTypeFieldNotPresentCondition(token.version(), BASE_INDENT),
406+
lengthOfLengthField,
407+
lengthCppType
408+
));
427409

428-
sb.append(String.format(
429-
indent + " std::uint64_t put%1$s(const char *src, const std::uint64_t length)\n" +
430-
indent + " {\n" +
431-
indent + " std::uint64_t lengthOfLengthField = %2$d;\n" +
432-
indent + " std::uint64_t lengthPosition = position();\n" +
433-
indent + " position(lengthPosition + lengthOfLengthField);\n" +
434-
indent + " *((%3$s *)(m_buffer + lengthPosition)) = %4$s((%3$s)length);\n" +
435-
indent + " std::uint64_t pos = position();\n" +
436-
indent + " position(position() + length);\n" +
437-
indent + " std::memcpy(m_buffer + pos, src, length);\n" +
438-
indent + " return length;\n" +
439-
indent + " }\n\n",
440-
propertyName,
441-
lengthOfLengthField,
442-
lengthCppType,
443-
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType())
444-
));
410+
sb.append(String.format(
411+
indent + " std::uint64_t get%1$s(char *dst, const std::uint64_t length)\n" +
412+
indent + " {\n" +
413+
"%2$s" +
414+
indent + " std::uint64_t lengthOfLengthField = %3$d;\n" +
415+
indent + " std::uint64_t lengthPosition = position();\n" +
416+
indent + " position(lengthPosition + lengthOfLengthField);\n" +
417+
indent + " std::uint64_t dataLength = %4$s(*((%5$s *)(m_buffer + lengthPosition)));\n" +
418+
indent + " std::uint64_t bytesToCopy = (length < dataLength) ? length : dataLength;\n" +
419+
indent + " std::uint64_t pos = position();\n" +
420+
indent + " position(position() + dataLength);\n" +
421+
indent + " std::memcpy(dst, m_buffer + pos, bytesToCopy);\n" +
422+
indent + " return bytesToCopy;\n" +
423+
indent + " }\n\n",
424+
propertyName,
425+
generateArrayFieldNotPresentCondition(token.version(), BASE_INDENT),
426+
lengthOfLengthField,
427+
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType()),
428+
lengthCppType
429+
));
445430

446-
sb.append(String.format(
447-
indent + " const std::string get%1$sAsString()\n" +
448-
indent + " {\n" +
449-
"%2$s" +
450-
indent + " std::uint64_t lengthOfLengthField = %3$d;\n" +
451-
indent + " std::uint64_t lengthPosition = position();\n" +
452-
indent + " position(lengthPosition + lengthOfLengthField);\n" +
453-
indent + " std::uint64_t dataLength = %4$s(*((%5$s *)(m_buffer + lengthPosition)));\n" +
454-
indent + " std::uint64_t pos = position();\n" +
455-
indent + " const std::string result(m_buffer + pos, dataLength);\n" +
456-
indent + " position(position() + dataLength);\n" +
457-
indent + " return std::move(result);\n" +
458-
indent + " }\n\n",
459-
propertyName,
460-
generateStringNotPresentCondition(token.version(), BASE_INDENT),
461-
lengthOfLengthField,
462-
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType()),
463-
lengthCppType
464-
));
431+
sb.append(String.format(
432+
indent + " std::uint64_t put%1$s(const char *src, const std::uint64_t length)\n" +
433+
indent + " {\n" +
434+
indent + " std::uint64_t lengthOfLengthField = %2$d;\n" +
435+
indent + " std::uint64_t lengthPosition = position();\n" +
436+
indent + " position(lengthPosition + lengthOfLengthField);\n" +
437+
indent + " *((%3$s *)(m_buffer + lengthPosition)) = %4$s((%3$s)length);\n" +
438+
indent + " std::uint64_t pos = position();\n" +
439+
indent + " position(position() + length);\n" +
440+
indent + " std::memcpy(m_buffer + pos, src, length);\n" +
441+
indent + " return length;\n" +
442+
indent + " }\n\n",
443+
propertyName,
444+
lengthOfLengthField,
445+
lengthCppType,
446+
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType())
447+
));
465448

466-
sb.append(String.format(
467-
indent + " %1$s &put%2$s(const std::string& str)\n" +
468-
indent + " {\n" +
469-
indent + " std::uint64_t lengthOfLengthField = %3$d;\n" +
470-
indent + " std::uint64_t lengthPosition = position();\n" +
471-
indent + " position(lengthPosition + lengthOfLengthField);\n" +
472-
indent + " *((%4$s *)(m_buffer + lengthPosition)) = %5$s((%4$s)str.length());\n" +
473-
indent + " std::uint64_t pos = position();\n" +
474-
indent + " position(position() + str.length());\n" +
475-
indent + " std::memcpy(m_buffer + pos, str.c_str(), str.length());\n" +
476-
indent + " return *this;\n" +
477-
indent + " }\n",
478-
className,
479-
propertyName,
480-
lengthOfLengthField,
481-
lengthCppType,
482-
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType())
483-
));
484-
}
449+
sb.append(String.format(
450+
indent + " const std::string get%1$sAsString()\n" +
451+
indent + " {\n" +
452+
"%2$s" +
453+
indent + " std::uint64_t lengthOfLengthField = %3$d;\n" +
454+
indent + " std::uint64_t lengthPosition = position();\n" +
455+
indent + " position(lengthPosition + lengthOfLengthField);\n" +
456+
indent + " std::uint64_t dataLength = %4$s(*((%5$s *)(m_buffer + lengthPosition)));\n" +
457+
indent + " std::uint64_t pos = position();\n" +
458+
indent + " const std::string result(m_buffer + pos, dataLength);\n" +
459+
indent + " position(position() + dataLength);\n" +
460+
indent + " return std::move(result);\n" +
461+
indent + " }\n\n",
462+
propertyName,
463+
generateStringNotPresentCondition(token.version(), BASE_INDENT),
464+
lengthOfLengthField,
465+
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType()),
466+
lengthCppType
467+
));
468+
469+
sb.append(String.format(
470+
indent + " %1$s &put%2$s(const std::string& str)\n" +
471+
indent + " {\n" +
472+
indent + " std::uint64_t lengthOfLengthField = %3$d;\n" +
473+
indent + " std::uint64_t lengthPosition = position();\n" +
474+
indent + " position(lengthPosition + lengthOfLengthField);\n" +
475+
indent + " *((%4$s *)(m_buffer + lengthPosition)) = %5$s((%4$s)str.length());\n" +
476+
indent + " std::uint64_t pos = position();\n" +
477+
indent + " position(position() + str.length());\n" +
478+
indent + " std::memcpy(m_buffer + pos, str.c_str(), str.length());\n" +
479+
indent + " return *this;\n" +
480+
indent + " }\n",
481+
className,
482+
propertyName,
483+
lengthOfLengthField,
484+
lengthCppType,
485+
formatByteOrderEncoding(lengthToken.encoding().byteOrder(), lengthToken.encoding().primitiveType())
486+
));
487+
488+
i += token.componentTokenCount();
485489
}
486490

487491
return sb;

0 commit comments

Comments
 (0)