Production ready converter from RFC's CSV file to CPP header
This commit is contained in:
parent
05c62be559
commit
2981a8d1d3
|
@ -9,14 +9,48 @@ use warnings;
|
|||
# to our C/C++ frndly storage format
|
||||
|
||||
open my $fl, "<", "ipfix_fields.csv" or die "Can't open input file";
|
||||
open my $target_h_file, ">", "ipfix_rfc.h" or die "Can't open file";
|
||||
open my $target_cpp_file, ">", "ipfix_rfc.cpp" or die "Can't open file";
|
||||
|
||||
|
||||
my $type_length_hash = {
|
||||
unsigned8 => 1,
|
||||
unsigned16 => 2,
|
||||
unsigned32 => 4,
|
||||
unsigned64 => 8,
|
||||
|
||||
ipv4Address => 4,
|
||||
ipv6Address => 16,
|
||||
|
||||
# types with unknown or variable length
|
||||
basicList => 0,
|
||||
boolean => 0,
|
||||
dateTimeMicroseconds => 0,
|
||||
dateTimeMilliseconds => 0,
|
||||
dateTimeNanoseconds => 0,
|
||||
dateTimeSeconds => 0,
|
||||
float64 => 0,
|
||||
macAddress => 0,
|
||||
octetArray => 0,
|
||||
string => 0,
|
||||
subTemplateList => 0,
|
||||
subTemplateMultiList => 0,
|
||||
};
|
||||
|
||||
my $field_id = 0;
|
||||
my @intervals = ();
|
||||
|
||||
my $fields = {};
|
||||
while (<$fl>) {
|
||||
chomp;
|
||||
|
||||
if (/^(\d+\-\d+)/) {
|
||||
push @intervals, $1;
|
||||
}
|
||||
|
||||
my $we_will_process_this_line = /^(\d+),/;
|
||||
|
||||
# Skip crap
|
||||
# Skip descriptions and other crap
|
||||
unless ($we_will_process_this_line) {
|
||||
next;
|
||||
}
|
||||
|
@ -28,15 +62,144 @@ while (<$fl>) {
|
|||
|
||||
$field_id++;
|
||||
|
||||
my @keys = ("id", "name", "data_type", "data_type_semantics", "status", "description","units", "range", "reference", "requester", "revision", "date");
|
||||
my @keys = ("id", "name", "data_type", "data_type_semantics", "status", "description",
|
||||
"units", "range", "reference", "requester", "revision", "date");
|
||||
|
||||
my %data = ();
|
||||
@data{ @keys } = split /,/, $_;
|
||||
|
||||
# skip deprecated fields
|
||||
if ($data{status} eq 'deprecated') {
|
||||
next;
|
||||
#print "$data{id} $data{name} $data{data_type}\n";
|
||||
$fields->{$data{"id"}} = \%data;
|
||||
}
|
||||
|
||||
for my $interval (@intervals) {
|
||||
my ($interval_start, $interval_end) = $interval =~ /^(\d+)\-(\d+)$/;
|
||||
|
||||
# Skip reserved interval up to 32767 because it's so long
|
||||
next if $interval_start == 433;
|
||||
|
||||
for my $field_id ($interval_start .. $interval_end) {
|
||||
$fields->{$field_id} = { id => $field_id, name => 'Reserved' };
|
||||
}
|
||||
|
||||
print "$data{id} $data{name} $data{data_type}\n";
|
||||
# print "Interval start $interval_start end $interval_end\n";
|
||||
}
|
||||
|
||||
for my $field_id (sort { $a <=> $b } keys %$fields) {
|
||||
my $data = $fields->{$field_id};
|
||||
|
||||
if ($data->{name} eq 'Reserved') {
|
||||
#print "$data->{id} $data->{name}\n";
|
||||
} else {
|
||||
#print "$data->{id} $data->{name} $data->{data_type}\n";
|
||||
}
|
||||
}
|
||||
|
||||
print {$target_h_file} <<DOC;
|
||||
#ifndef __IPFIX_RFC_H__
|
||||
#define __IPFIX_RFC_H__
|
||||
|
||||
/* This file is autogenerated with script ipfix_csv_processor.pl */
|
||||
/* Please do not edit it directly */
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
class ipfix_information_element_t {
|
||||
public:
|
||||
ipfix_information_element_t(std::string name, unsigned int length);
|
||||
ipfix_information_element_t();
|
||||
std::string get_name();
|
||||
unsigned int get_length();
|
||||
std::string name;
|
||||
unsigned int length;
|
||||
};
|
||||
|
||||
typedef std::map<unsigned int, ipfix_information_element_t> ipfix_database_t;
|
||||
class ipfix_information_database {
|
||||
public:
|
||||
ipfix_information_database();
|
||||
bool add_element(unsigned int field_id, std::string name, unsigned int length);
|
||||
std::string get_name_by_id(unsigned int field_id);
|
||||
unsigned int get_length_by_id(unsigned int field_id);
|
||||
private:
|
||||
ipfix_database_t database;
|
||||
};
|
||||
|
||||
#endif
|
||||
DOC
|
||||
|
||||
print {$target_cpp_file} <<DOC;
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include "ipfix_rfc.h"
|
||||
|
||||
/* This file is autogenerated with script ipfix_csv_processor.pl */
|
||||
/* Please do not edit it directly */
|
||||
|
||||
std::string ipfix_information_element_t::get_name() {
|
||||
return this->name;
|
||||
}
|
||||
|
||||
unsigned int ipfix_information_element_t::get_length() {
|
||||
return this->length;
|
||||
}
|
||||
|
||||
ipfix_information_element_t::ipfix_information_element_t(std::string name, unsigned int length) {
|
||||
this->name = name;
|
||||
this->length = length;
|
||||
}
|
||||
|
||||
std::string ipfix_information_database::get_name_by_id(unsigned int field_id) {
|
||||
ipfix_database_t::iterator itr = database.find(field_id);
|
||||
|
||||
if (itr == database.end()) {
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
return itr->second.get_name();
|
||||
}
|
||||
|
||||
unsigned int ipfix_information_database::get_length_by_id(unsigned int field_id) {
|
||||
ipfix_database_t::iterator itr = database.find(field_id);
|
||||
|
||||
if (itr == database.end()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return itr->second.get_length();
|
||||
}
|
||||
|
||||
bool ipfix_information_database::add_element(unsigned int field_id, std::string name, unsigned int length) {
|
||||
ipfix_database_t::iterator itr = database.find(field_id);
|
||||
|
||||
// Duplicate ID's strictly prohibited
|
||||
if (itr != database.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
database[field_id] = ipfix_information_element_t(name, length);
|
||||
return true;
|
||||
}
|
||||
|
||||
ipfix_information_database::ipfix_information_database() {
|
||||
DOC
|
||||
|
||||
for my $field_id (sort { $a <=> $b } keys %$fields) {
|
||||
my $data = $fields->{$field_id};
|
||||
|
||||
my $field_length = 0;
|
||||
my $field_name = '"reserved"';
|
||||
|
||||
if ($data->{"data_type"}) {
|
||||
$field_length = $type_length_hash->{ $data->{"data_type"} };
|
||||
}
|
||||
|
||||
if (defined($data->{"name"}) && $data->{"name"}) {
|
||||
$field_name = "\"$data->{'name'}\"";
|
||||
}
|
||||
|
||||
print {$target_cpp_file} " this->add_element($field_id, $field_name, $field_length);\n";
|
||||
}
|
||||
|
||||
print {$target_cpp_file} "}\n";
|
||||
|
|
Loading…
Reference in New Issue