<'
# Copyright (c) 2011-2013, 2017-2018, 2023-2024, 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 Tue Nov 29 2011
#
#

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

lang c

# compute handy shortcuts
set comp [$component name]
set COMP [string toupper [$component name]]
'>

#ifndef H_GROS_<"$COMP">_SERVICE
#define H_GROS_<"$COMP">_SERVICE

#include "ros/serialization.h"

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

<'foreach s $services {'>
<'  set inplist [$s parameters in inout]'>
<'  set outplist [$s parameters out inout]'>

/* <"[--- Service [$s name] ------------------------------------------------]"> */

<'  if {[$s kind] != "activity"} {'>
#include "<"$comp">_ros/srv/<"[$s name]">.srv.md5"
<'  } else {'>
#include "<"$comp">_ros/msg/<"[$s name]">ActionGoal.msg.md5"
#include "<"$comp">_ros/msg/<"[$s name]">ActionResult.msg.md5"
<'  }'>

namespace <"$comp">_genom {
  namespace srv_<"[$s name]"> {
    struct genom_input {
<'  foreach p $inplist {'>
      <"[[$p type] declarator [$p name]]">;
<'  }'>

      boost::shared_ptr<std::map<std::string, std::string> > __connection_header;

      genom_input() {
<'  foreach p $inplist {'>
        genom_tinit_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">);
<'  }'>
      }

      ~genom_input() {
<'  foreach p $inplist {'>
        genom_tfini_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">);
<'  }'>
      }

      genom_input &operator=(const genom_input &<'if {[llength $inplist]} {'>src<'}'>) {
<'  foreach p $inplist {'>
        genom_tinit_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">);
        genom_tcopy_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">,
          <"[[$p type] pass value src.[$p name]]">);
<'  }'>
        return *this;
      }
    };

    struct genom_output {
      uint8_t genom_success;
      std::string genom_exdetail;
<'  foreach p $outplist {'>
      <"[[$p type] declarator [$p name]]">;
<'  }'>

      boost::shared_ptr<std::map<std::string, std::string> > __connection_header;

      genom_output():genom_success(1),genom_exdetail() {
<'  foreach p [$s parameters inout out] {'>
        genom_tinit_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">);
<'  }'>
      }

      ~genom_output() {
<'  foreach p $outplist {'>
        genom_tfini_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">);
<'  }'>
      }

      genom_output &operator=(const genom_output &src) {
        genom_success = src.genom_success;
        genom_exdetail = src.genom_exdetail;
<'  foreach p $outplist {'>
        genom_tinit_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">);
        genom_tcopy_<"[[$p type] mangle]">(
          <"[[$p type] pass reference [$p name]]">,
          <"[[$p type] pass value src.[$p name]]">);
<'  }'>
        return *this;
      }
    };
  };
};

namespace ros {
  namespace message_traits {
    template<> struct IsMessage<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input >: TrueType {};
    template<> struct IsMessage<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input const>: TrueType {};
    template<> struct IsMessage<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output >: TrueType {};
    template<> struct IsMessage<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output const>: TrueType {};

    template<> struct IsFixedSize<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input >: TrueType {};
    template<> struct IsFixedSize<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output >: TrueType {};

    template<> struct MD5Sum<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input > {
      static const char* value()
      {
<'  if {[$s kind] != "activity"} {'>
        return genom_md5_<"[$s name]">;
<'  } else {'>
        return genom_md5_<"[$s name]">ActionGoal;
<'  }'>
      }

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

    template<> struct MD5Sum<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output > {
      static const char* value()
      {
<'  if {[$s kind] != "activity"} {'>
        return genom_md5_<"[$s name]">;
<'  } else {'>
        return genom_md5_<"[$s name]">ActionResult;
<'  }'>
      }

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

    template<> struct DataType<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input > {
      static const char* value() {
<'  if {[$s kind] != "activity"} {'>
        return "<"$comp">_ros/<"[$s name]">";
<'  } else {'>
        return "<"$comp">_ros/<"[$s name]">ActionGoal";
<'  }'>
      }

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

    template<> struct DataType<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output > {
      static const char* value() {
<'  if {[$s kind] != "activity"} {'>
        return "<"$comp">_ros/<"[$s name]">";
<'  } else {'>
        return "<"$comp">_ros/<"[$s name]">ActionResult";
<'  }'>
      }

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

    template<> struct Definition<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input > {
      static const char* value()
      {
        return "<"[string map {\n \\n\\\n} [rossrv $s]]">";
      }

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

    template<> struct Definition<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output > {
      static const char* value()
      {
        return "<"[string map {\n \\n\\\n} [rossrv $s]]">";
      }

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

<'  if {[$s kind] != "activity"} {'>
  namespace service_traits {
    template<> struct MD5Sum<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input > {
      static const char* value()
      {
        return genom_md5_<"[$s name]">;
      }

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

    template<> struct MD5Sum<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output > {
      static const char* value()
      {
        return genom_md5_<"[$s name]">;
      }

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

    template<> struct DataType<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input > {
      static const char* value() {
        return "<"$comp">_ros/<"[$s name]">";
      }

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

    template<> struct DataType<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output > {
      static const char* value() {
        return "<"$comp">_ros/<"[$s name]">";
      }

      static const char*
        value(const ::<"$comp">_genom::srv_<"[$s name]">::genom_output &) {
        return value();
      }
    };
  };
<'  }'>

  namespace serialization {
    template<> struct Serializer<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_input > {
      template<typename Stream, typename T>
      inline static void allInOne(Stream& <'if {[llength $inplist]} {'>stream<'}'>,
                                  T<'if {[llength $inplist]} {'> m<'}'>) {
<'  foreach p $inplist {
    switch -- [[$p type] kind] {
      array {
        set l [[$p type] length]
'>
        for(uint32_t i = 0; i < <"$l">; i++) {
          stream.next(m.<"[$p name]">[i]);
        }
<'      }
      default {'>
        stream.next(m.<"[$p name]">);
<'      }
    }
  }'>
      }

      ROS_DECLARE_ALLINONE_SERIALIZER;
    };

    template<> struct Serializer<
      ::<"$comp">_genom::srv_<"[$s name]">::genom_output > {
      template<typename Stream, typename T>
      inline static void allInOne(Stream& stream, T m) {
        stream.next(m.genom_success);
        stream.next(m.genom_exdetail);

<'  foreach p $outplist {
    switch -- [[$p type] kind] {
      array {
        set l [[$p type] length]
'>
        for(uint32_t i = 0; i < <"$l">; i++) {
          stream.next(m.<"[$p name]">[i]);
        }
<'      }
      default {'>
        stream.next(m.<"[$p name]">);
<'      }
    }
  }'>
      }

      ROS_DECLARE_ALLINONE_SERIALIZER;
    };
  };
};

<'}'>

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