<'
#
# Copyright (c) 2011-2012, 2018, 2023, 2026 LAAS/CNRS
# All rights reserved.
#
# Redistribution and use  in source  and binary  forms,  with or without
# modification, are permitted provided that the following conditions are
# met:
#
#   1. Redistributions of  source  code must retain the  above copyright
#      notice and this list of conditions.
#   2. Redistributions in binary form must reproduce the above copyright
#      notice and  this list of  conditions in the  documentation and/or
#      other materials provided with the distribution.
#
#                                      Anthony Mallet on Thu Dec 15 2011
#
#

# check arguments
if {[llength $argv] != 1} { error "expected arguments: component" }
lassign $argv component

lang c

# compute handy shortcuts
set comp [$component name]
set roscomp genom_$comp
set COMP [string toupper [$component name]]
'>
#ifndef H_GROS_<"$COMP">_PORTLIB
#define H_GROS_<"$COMP">_PORTLIB

#include <pthread.h>

#include <cstdlib>
#include <cstring>
#include <map>

#include "ros/ros.h"
#include "ros/serialization.h"

#include "<"$comp">_serialize.h"
#include "typeops-c.h"

<'foreach p [$component ports] {'>

/* <"[--- Port [$p name] ---------------------------------------------------]"> */

<'  if {[catch {[$p datatype] masquerade ros} masquerade]} {'>
#include "<"$comp">_ros/msg/<"[rosmsg_cname [$p datatype]]">.msg.md5"
<'  } else {'>
#include "<"$masquerade">.h"
<'  }'>

namespace <"$comp">_genom {
  struct port_<"[$p name]"> {
    ::<"[[$p datatype] declarator v]">;
    boost::shared_ptr<std::map<std::string, std::string> > __connection_header;

    port_<"[$p name]">() {
      genom_tinit_<"[[$p datatype] mangle]">(
          <"[[$p datatype] pass reference v]">);
    }

    ~port_<"[$p name]">() {
      genom_tfini_<"[[$p datatype] mangle]">(
          <"[[$p datatype] pass reference v]">);
    }
  };
};

namespace ros {
  namespace message_traits {
    template<> struct IsMessage<
      ::<"$comp">_genom::port_<"[$p name]"> > : TrueType {};
    template<> struct IsMessage<
      ::<"$comp">_genom::port_<"[$p name]"> const > : TrueType {};

    template<> struct MD5Sum<
      ::<"$comp">_genom::port_<"[$p name]"> > {
      static const char *value() {
<'  if {[catch {[$p datatype] masquerade ros} masquerade]} {'>
        return genom_md5_<"[rosmsg_cname [$p datatype]]">;
<'  } else {'>
        return MD5Sum< <"[string map {/ ::} $masquerade]"> >::value();
<'  }'>
      }

      static const char*
        value(const ::<"$comp">_genom::port_<"[$p name]"> &) {
        return value();
      }
    };

    template<> struct DataType<
      ::<"$comp">_genom::port_<"[$p name]"> > {
      static const char* value() {
<'  if {[catch {[$p datatype] masquerade ros} masquerade]} {'>
        return "<"$comp">_ros/<"[rosmsg_cname [$p datatype]]">";
<'  } else {'>
        return DataType< <"[string map {/ ::} $masquerade]"> >::value();
<'  }'>
      }

      static const char*
        value(const ::<"$comp">_genom::port_<"[$p name]"> &) {
        return value();
      }
    };

    template<> struct Definition<
      ::<"$comp">_genom::port_<"[$p name]"> > {
      static const char* value()
      {
<'  if {[catch {[$p datatype] masquerade ros} masquerade]} {'>
        return genom_dcat_<"[rosmsg_cname [$p datatype]]">;
<'  } else {'>
        return Definition< <"[string map {/ ::} $masquerade]"> >::value();
<'  }'>
      }

      static const char*
        value(const ::<"$comp">_genom::port_<"[$p name]"> &) {
        return value();
      }
    };
  };

  namespace serialization {
    template<> struct Serializer<
      ::<"$comp">_genom::port_<"[$p name]"> > {
      template<typename Stream, typename T>
        inline static void allInOne(Stream& stream, T m) {
        stream.next(m.v);
      }
      ROS_DECLARE_ALLINONE_SERIALIZER;
    };
  };
};

<'}'>

#endif /* H_GROS_<"$COMP">_PORTLIB */
