#!/usr/bin/ruby
# 通信パケットのジェネレーター
# Satofumi KAMIMURA
# $Id: command_generator.rb 1361 2009-10-03 06:21:34Z satofumi $

header_file =
  "#ifndef PACKET_ACCESS_H\n" +
  "#define PACKET_ACCESS_H\n" +
  "\n" +
  "#include \"robot_t.h\"\n" +
  "#include <vector>\n" +
  "\n\n"

source_file =
  "#include \"PacketAccess.h\"\n" +
  "\n\n" +
  "namespace\n" +
  "{\n" +
  "  void setValue(std::vector<char>& packet, unsigned long value, size_t byte_size)\n" +
  "  {\n" +
  "    for (size_t i = 0; i < byte_size; ++i) {\n" +
  "      packet.push_back(value >> (8 * (byte_size - i - 1)));\n" +
  "    }\n" +
  "    ++packet[6];\n" +
  "  }\n" +
  "\n\n" +
  "  unsigned long getValue(unsigned char*& p, size_t byte_size)\n" +
  "  {\n" +
  "    unsigned long value = 0;\n" +
  "    for (size_t i = 0; i < byte_size; ++i) {\n" +
  "      value <<= 8;\n" +
  "      value |= *p++;\n" +
  "    }\n" +
  "    return value;\n" +
  "  }\n" +
  "}\n"


File.open("beego_drive/struct_offset.txt") { |io|
  while line = io.gets
    # １行毎に setter, getter 関数を生成する

    tokens = line.chomp.split(", ")
    base_name = tokens[0].gsub("\.", "_")
    type = tokens[3]
    offset = tokens[1]

    setter = "void " + base_name + "_set(std::vector<char>& packet, " + type + " value)"
    getter = type + " " + base_name + "_get(unsigned char*& p)"

    # ヘッダファイルの出力
    header_file = header_file + "extern " + setter + ";\n"
    header_file = header_file + "extern " + getter + ";\n"

    source_file = source_file + "\n\n" +
      setter + "\n" +
      "{\n" +
      "  packet.push_back(" + offset + ");\n" +
      "  size_t byte_size = sizeof(" + type + ");\n" +
      "  packet.push_back(byte_size);\n" +
      "  setValue(packet, value, byte_size);\n" +
      "}\n"

    source_file = source_file + "\n\n" +
      getter + "\n" +
      "{\n" +
      "  ++p;\n" +
      "  size_t byte_size = *p++;\n" +
      "  return static_cast<" + type + ">(getValue(p, byte_size));\n" +
      "}\n"
  end
}

# ファイル末尾に出力を追加
header_file = header_file +
  "\n" +
  "#endif /* !PACKET_ACCESS_H */\n"


# ファイル出力
File.open("PacketAccess.h", "w") { |io|
  io.print header_file
}

File.open("PacketAccess.cpp", "w") { |io|
  io.print source_file
}
