blob: 4f26d04c3165d8fbbcaf3b4e86be6d4d34a2d155 [file] [log] [blame]
require_relative 'load.rb'
# TODO(brians): Special-case Time too and float/double if we can find a good way to do it.
GenericTypeNames = ['float', 'double', 'char']
TimeTypeNames = ['::aos::monotonic_clock::time_point']
IntegerSizes = [8, 16, 32, 64]
WriteIffChanged.open(ARGV[0]) do |output|
output.puts <<END
// This file is generated by #{File.expand_path(__FILE__)}.
// DO NOT EDIT BY HAND!
#include <sys/types.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include "aos/byteorder.h"
#include "aos/time/time.h"
#include "aos/print_field_helpers.h"
#include "aos/logging/printf_formats.h"
namespace aos {
bool PrintField(char *output, size_t *output_bytes, const void *input,
size_t *input_bytes, uint32_t type) {
switch (type) {
#{GenericTypeNames.collect do |name|
message_element = Target::MessageElement.new(name, 'value')
statement = MessageElementStmt.new(name, 'value')
message_element.size = statement.size
print_args = []
message_element.fetchPrintArgs(print_args)
next <<END2
case #{message_element.getTypeID()}:
{
if (*input_bytes < #{statement.size}) return false;
*input_bytes -= #{statement.size};
#{name} value;
to_host(static_cast<const char *>(input), &value);
int ret = snprintf(output, *output_bytes,
"#{statement.toPrintFormat()}",
#{print_args[0]});
if (ret < 0) return false;
if (static_cast<unsigned int>(ret) >= *output_bytes) return false;
*output_bytes -= ret;
return true;
}
END2
end.join('')}
#{TimeTypeNames.collect do |name|
message_element = Target::MessageElement.new(name, 'value')
statement = MessageElementStmt.new(name, 'value')
message_element.size = statement.size
print_args = []
message_element.fetchPrintArgs(print_args)
next <<END2
case #{message_element.getTypeID()}:
{
if (*input_bytes < #{statement.size}) return false;
*input_bytes -= #{statement.size};
int32_t upper;
uint32_t lower;
to_host(static_cast<const char *>(input), &upper);
to_host(static_cast<const char *>(input) + 4, &lower);
#{name} value(::std::chrono::seconds(upper) + ::std::chrono::nanoseconds(lower));
int ret = snprintf(output, *output_bytes,
"#{statement.toPrintFormat()}",
#{print_args[0]});
if (ret < 0) return false;
if (static_cast<unsigned int>(ret) >= *output_bytes) return false;
*output_bytes -= ret;
return true;
}
END2
end.join('')}
#{IntegerSizes.collect do |size|
[true, false].collect do |signed|
size_bytes = size / 8
name = "#{signed ? '' : 'u'}int#{size}_t"
message_element = Target::MessageElement.new(name, 'value')
message_element.size = size_bytes
next <<END2
case #{message_element.getTypeID()}:
{
if (*input_bytes < #{size_bytes}) return false;
*input_bytes -= #{size_bytes};
#{name} value;
to_host(static_cast<const char *>(input), &value);
return PrintInteger<#{name}>(output, value, output_bytes);
}
END2
end
end.flatten.join('')}
#{
message_element = Target::MessageElement.new('bool', 'value')
message_element.size = 1
r = <<END2
case #{message_element.getTypeID()}:
{
if (*input_bytes < 1) return false;
if (*output_bytes < 1) return false;
*input_bytes -= 1;
bool value = static_cast<const char *>(input)[0];
*output_bytes -= 1;
*output = value ? 'T' : 'f';
return true;
}
END2
}
default:
return false;
}
}
} // namespace aos
END
end