writeGeneralCodec method

  1. @override
void writeGeneralCodec(
  1. GObjectOptions generatorOptions,
  2. Root root,
  3. Indent indent, {
  4. required String dartPackageName,
})
override

Writes the custom codec to indent.

Implementation

@override
void writeGeneralCodec(
  GObjectOptions generatorOptions,
  Root root,
  Indent indent, {
  required String dartPackageName,
}) {
  final String module = _getModule(generatorOptions, dartPackageName);
  final String codecClassName = _getClassName(module, _codecBaseName);
  final String codecMethodPrefix = _getMethodPrefix(module, _codecBaseName);

  final Iterable<EnumeratedType> customTypes = getEnumeratedTypes(root);

  indent.newln();
  _writeObjectStruct(indent, module, _codecBaseName, () {},
      parentClassName: _standardCodecName);

  indent.newln();
  _writeDefineType(indent, module, _codecBaseName,
      parentType: 'fl_standard_message_codec_get_type()');

  for (final EnumeratedType customType in customTypes) {
    final String customTypeName = _getClassName(module, customType.name);
    final String snakeCustomTypeName =
        _snakeCaseFromCamelCase(customTypeName);
    indent.newln();
    final String valueType = customType.type == CustomTypes.customClass
        ? '$customTypeName*'
        : 'FlValue*';
    indent.writeScoped(
        'static gboolean ${codecMethodPrefix}_write_$snakeCustomTypeName($_standardCodecName* codec, GByteArray* buffer, $valueType value, GError** error) {',
        '}', () {
      indent.writeln('uint8_t type = ${customType.enumeration};');
      indent.writeln('g_byte_array_append(buffer, &type, sizeof(uint8_t));');
      if (customType.type == CustomTypes.customClass) {
        indent.writeln(
            'g_autoptr(FlValue) values = ${snakeCustomTypeName}_to_list(value);');
        indent.writeln(
            'return fl_standard_message_codec_write_value(codec, buffer, values, error);');
      } else if (customType.type == CustomTypes.customEnum) {
        indent.writeln(
            'return fl_standard_message_codec_write_value(codec, buffer, value, error);');
      }
    });
  }

  indent.newln();
  indent.writeScoped(
      'static gboolean ${codecMethodPrefix}_write_value($_standardCodecName* codec, GByteArray* buffer, FlValue* value, GError** error) {',
      '}', () {
    indent.writeScoped(
        'if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) {', '}', () {
      indent.writeScoped('switch (fl_value_get_custom_type(value)) {', '}',
          () {
        for (final EnumeratedType customType in customTypes) {
          indent.writeln('case ${customType.enumeration}:');
          indent.nest(1, () {
            final String customTypeName =
                _getClassName(module, customType.name);
            final String snakeCustomTypeName =
                _snakeCaseFromCamelCase(customTypeName);
            final String castMacro =
                _getClassCastMacro(module, customType.name);
            if (customType.type == CustomTypes.customClass) {
              indent.writeln(
                  'return ${codecMethodPrefix}_write_$snakeCustomTypeName(codec, buffer, $castMacro(fl_value_get_custom_value_object(value)), error);');
            } else if (customType.type == CustomTypes.customEnum) {
              indent.writeln(
                  'return ${codecMethodPrefix}_write_$snakeCustomTypeName(codec, buffer, reinterpret_cast<FlValue*>(const_cast<gpointer>(fl_value_get_custom_value(value))), error);');
            }
          });
        }
      });
    });

    indent.newln();
    indent.writeln(
        'return FL_STANDARD_MESSAGE_CODEC_CLASS(${codecMethodPrefix}_parent_class)->write_value(codec, buffer, value, error);');
  });

  for (final EnumeratedType customType in customTypes) {
    final String customTypeName = _getClassName(module, customType.name);
    final String snakeCustomTypeName =
        _snakeCaseFromCamelCase(customTypeName);
    indent.newln();
    indent.writeScoped(
        'static FlValue* ${codecMethodPrefix}_read_$snakeCustomTypeName($_standardCodecName* codec, GBytes* buffer, size_t* offset, GError** error) {',
        '}', () {
      if (customType.type == CustomTypes.customClass) {
        indent.writeln(
            'g_autoptr(FlValue) values = fl_standard_message_codec_read_value(codec, buffer, offset, error);');
        indent.writeScoped('if (values == nullptr) {', '}', () {
          indent.writeln('return nullptr;');
        });
        indent.newln();
        indent.writeln(
            'g_autoptr($customTypeName) value = ${snakeCustomTypeName}_new_from_list(values);');
        indent.writeScoped('if (value == nullptr) {', '}', () {
          indent.writeln(
              'g_set_error(error, FL_MESSAGE_CODEC_ERROR, FL_MESSAGE_CODEC_ERROR_FAILED, "Invalid data received for MessageData");');
          indent.writeln('return nullptr;');
        });
        indent.newln();
        indent.writeln(
            'return fl_value_new_custom_object(${customType.enumeration}, G_OBJECT(value));');
      } else if (customType.type == CustomTypes.customEnum) {
        indent.writeln(
            'return fl_value_new_custom(${customType.enumeration}, fl_standard_message_codec_read_value(codec, buffer, offset, error), (GDestroyNotify)fl_value_unref);');
      }
    });
  }

  indent.newln();
  indent.writeScoped(
      'static FlValue* ${codecMethodPrefix}_read_value_of_type($_standardCodecName* codec, GBytes* buffer, size_t* offset, int type, GError** error) {',
      '}', () {
    indent.writeScoped('switch (type) {', '}', () {
      for (final EnumeratedType customType in customTypes) {
        final String customTypeName = _getClassName(module, customType.name);
        final String snakeCustomTypeName =
            _snakeCaseFromCamelCase(customTypeName);
        indent.writeln('case ${customType.enumeration}:');
        indent.nest(1, () {
          indent.writeln(
              'return ${codecMethodPrefix}_read_$snakeCustomTypeName(codec, buffer, offset, error);');
        });
      }

      indent.writeln('default:');
      indent.nest(1, () {
        indent.writeln(
            'return FL_STANDARD_MESSAGE_CODEC_CLASS(${codecMethodPrefix}_parent_class)->read_value_of_type(codec, buffer, offset, type, error);');
      });
    });
  });

  indent.newln();
  _writeInit(indent, module, _codecBaseName, () {});

  indent.newln();
  _writeClassInit(indent, module, _codecBaseName, () {
    indent.writeln(
        'FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->write_value = ${codecMethodPrefix}_write_value;');
    indent.writeln(
        'FL_STANDARD_MESSAGE_CODEC_CLASS(klass)->read_value_of_type = ${codecMethodPrefix}_read_value_of_type;');
  }, hasDispose: false);

  indent.newln();
  indent.writeScoped(
      'static $codecClassName* ${codecMethodPrefix}_new() {', '}', () {
    _writeObjectNew(indent, module, _codecBaseName);
    indent.writeln('return self;');
  });
}