| <#-- |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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 |
| |
| http://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. |
| --> |
| <#-- Prevent freemarker from escaping stuff --> |
| <#outputformat "undefined"> |
| <#-- Declare the name and type of variables passed in to the template --> |
| <#-- @ftlvariable name="languageName" type="java.lang.String" --> |
| <#-- @ftlvariable name="protocolName" type="java.lang.String" --> |
| <#-- @ftlvariable name="outputFlavor" type="java.lang.String" --> |
| <#-- @ftlvariable name="helper" type="org.apache.plc4x.language.c.CLanguageTemplateHelper" --> |
| <#-- @ftlvariable name="type" type="org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition" --> |
| <#-- Declare the name and type of variables declared locally inside the template --> |
| <#-- @ftlvariable name="field" type="org.apache.plc4x.plugins.codegenerator.types.fields.NamedField" --> |
| <#if !helper.isDiscriminatedChildTypeDefinition(type)>${helper.getIncludesDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(type.name)}.h |
| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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 |
| |
| http://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. |
| */ |
| #ifndef ${helper.getCTypeName(type.name)?upper_case}_H_ |
| #define ${helper.getCTypeName(type.name)?upper_case}_H_ |
| |
| #include <stdbool.h> |
| #include <stdint.h> |
| #include <plc4c/spi/read_buffer.h> |
| #include <plc4c/spi/write_buffer.h> |
| #include <plc4c/utils/list.h> |
| <#-- |
| Add any import statements for partent-types, complex types used in properties or parser arguments. |
| --> |
| <#if helper.getComplexTypeReferences()?has_content> |
| <#list helper.getComplexTypeReferences() as typeReference> |
| #include "${helper.camelCaseToSnakeCase(typeReference)}.h" |
| </#list> |
| </#if> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| <#-- |
| Abstract types only occur as parents in the case of discriminated types. |
| As C doesn't have any form of polymorph type-system, we need to save the type information in the |
| data-structure. So with this enum we're doing exactly this. It will be used in the serializers and |
| parsers and stored in discriminated types. |
| --> |
| <#if helper.isDiscriminatedParentTypeDefinition(type)> |
| |
| // Structure used to contain the discriminator values for discriminated types using this as a parent |
| struct ${helper.getCTypeName(type.name)}_discriminator { |
| <#if helper.getDiscriminatorTypes()?has_content> |
| <#list helper.getDiscriminatorTypes()?keys as discriminatorName> |
| ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} ${discriminatorName}; |
| </#list> |
| </#if> |
| }; |
| typedef struct ${helper.getCTypeName(type.name)}_discriminator ${helper.getCTypeName(type.name)}_discriminator; |
| |
| // Enum assigning each sub-type an individual id. |
| enum ${helper.getCTypeName(type.name)}_type { |
| <#list helper.getSubTypeDefinitions() as subtype> |
| ${helper.getCTypeName(type.name)}_type_${helper.getCTypeName(subtype.name)} = ${subtype?index}<#sep>, |
| </#list> |
| }; |
| typedef enum ${helper.getCTypeName(type.name)}_type ${helper.getCTypeName(type.name)}_type; |
| |
| // Function to get the discriminator values for a given type. |
| ${helper.getCTypeName(type.name)}_discriminator ${helper.getCTypeName(type.name)}_get_discriminator(${helper.getCTypeName(type.name)}_type type); |
| </#if> |
| <#-- |
| When using const fields, output the constant reference values |
| as global const values so we can use them elsewhere. |
| --> |
| <#if helper.getAllConstFields()?has_content> |
| |
| // Constant values. |
| <#list helper.getAllConstFields() as parentType, constField> |
| ${helper.getLanguageTypeNameForField(constField)} ${helper.getCTypeName(parentType.name)?upper_case}_${helper.camelCaseToSnakeCase(constField.name)?upper_case}(); |
| </#list> |
| </#if> |
| |
| <#-- |
| Create the general data-structure for this type |
| --> |
| struct ${helper.getCTypeName(type.name)} { |
| <#if helper.isDiscriminatedParentTypeDefinition(type)> |
| /* This is an abstract type so this property saves the type of this typed union */ |
| ${helper.getCTypeName(type.name)}_type _type; |
| </#if> |
| /* Properties */ |
| <#list helper.getPropertyAndSwitchFields() as field> |
| <#if helper.isSwitchField(field)> |
| union { |
| <#list field.cases as case> |
| struct { /* ${case.name} */ |
| <#list case.propertyFields as caseField> |
| <#if (helper.isSimpleTypeReference(caseField.type) || helper.isEnumField(caseField)) && !helper.isOptionalField(caseField) && !helper.isArrayField(caseField) && !helper.isManualArrayField(caseField)> |
| ${helper.getLanguageTypeNameForField(caseField)} ${helper.camelCaseToSnakeCase(case.name)}_${helper.camelCaseToSnakeCase(caseField.name)}${helper.getTypeSizeForField(caseField)}<#if field.loopType??>${helper.getLoopExpressionSuffix(caseField)}</#if>; |
| <#elseif helper.isArrayField(caseField) || helper.isManualArrayField(caseField)> |
| plc4c_list* ${helper.camelCaseToSnakeCase(case.name)}_${helper.camelCaseToSnakeCase(caseField.name)}; |
| <#else> |
| ${helper.getLanguageTypeNameForField(caseField)}* ${helper.camelCaseToSnakeCase(case.name)}_${helper.camelCaseToSnakeCase(caseField.name)}; |
| </#if> |
| </#list> |
| }; |
| </#list> |
| }; |
| <#elseif (helper.isSimpleTypeReference(field.type) || helper.isEnumField(field)) && !helper.isOptionalField(field) && !helper.isArrayField(field) && !helper.isManualArrayField(field)> |
| ${helper.getLanguageTypeNameForField(field)} ${helper.camelCaseToSnakeCase(field.name)}${helper.getTypeSizeForField(field)}<#if field.loopType??>${helper.getLoopExpressionSuffix(field)}</#if>; |
| <#elseif helper.isArrayField(field) || helper.isManualArrayField(field)> |
| plc4c_list* ${helper.camelCaseToSnakeCase(field.name)}; |
| <#else> |
| ${helper.getLanguageTypeNameForField(field)}* ${helper.camelCaseToSnakeCase(field.name)}; |
| </#if> |
| </#list> |
| }; |
| typedef struct ${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}; |
| |
| // Create an empty NULL-struct |
| ${helper.getCTypeName(type.name)} ${helper.getCTypeName(type.name)}_null(); |
| |
| <#-- |
| Define the parse-method for elements of this tpye |
| --> |
| plc4c_return_code ${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* io, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>${helper.getCTypeName(type.name)}** message); |
| |
| <#-- |
| Define the serialize-method for elements of this tpye |
| --> |
| plc4c_return_code ${helper.getCTypeName(type.name)}_serialize(plc4c_spi_write_buffer* io, ${helper.getCTypeName(type.name)}* message<#if helper.getSerializerArguments(type.parserArguments)?has_content>, <#list helper.getSerializerArguments(type.parserArguments) as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)} ${parserArgument.name}<#sep>, </#sep></#list></#if>); |
| |
| uint16_t ${helper.getCTypeName(type.name)}_length_in_bytes(${helper.getCTypeName(type.name)}* message); |
| |
| uint16_t ${helper.getCTypeName(type.name)}_length_in_bits(${helper.getCTypeName(type.name)}* message); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| #endif // ${helper.getCTypeName(type.name)?upper_case}_H_ |
| </#if> |
| </#outputformat> |