Add management of version and new decoder signature.
[src/low-level-can-generator.git] / src / openxc / decoder.cpp
1 #include "decoder.hpp"
2
3 map_decoders decoder_t::decoders_states_;
4 std::string decoder_t::patchs_;
5
6
7 void decoder_t::init_decoder()
8 {
9     decoder_t::decoders_states_.insert(pair_decoder("decode_state", states::NATIVE));
10     decoder_t::decoders_states_.insert(pair_decoder("decode_boolean", states::NATIVE));
11     decoder_t::decoders_states_.insert(pair_decoder("decode_ignore", states::NATIVE));
12     decoder_t::decoders_states_.insert(pair_decoder("decode_noop", states::NATIVE));
13     decoder_t::decoders_states_.insert(pair_decoder("decode_bytes", states::NATIVE));
14     decoder_t::decoders_states_.insert(pair_decoder("decode_obd2_response", states::NATIVE));
15 }
16
17
18 std::string decoder_t::add_decoder(std::string decoder, std::string version_file, std::string version_low_can)
19 {
20     if(decoder.compare("nullptr"))
21     {
22         std::string key = "decoder_t::";
23         std::size_t pos = decoder.find(key);
24         std::string decoder_split =  decoder.substr(pos+key.size()); // only name of decoder
25
26         if ( decoder_t::decoders_states_.find(decoder_split) == decoder_t::decoders_states_.end() ) { // Not found signal
27             decoder_t::decoders_states_.insert(pair_decoder(decoder_split,states::NEW));
28             std::string ret = key + decoder_t::patch_version(decoder_split,version_file,version_low_can);
29             decoder_t::decoders_states_[decoder_split] = states::PROCESSED;
30             return ret;
31         }
32         else
33         {
34             if(decoder_t::decoders_states_[decoder_split] == states::PROCESSED)
35             {
36                 return key + decoder_t::patch_version(decoder_split,version_file,version_low_can);
37             }
38         }
39     }
40     return decoder;
41 }
42
43
44 std::string decoder_t::patch_version(std::string decoder, std::string version_file, std::string version_low_can)
45 {
46     std::size_t pos = version_file.find(".");
47     int main_value_version_file = std::stoi(version_file.substr(0,pos));
48
49     std::size_t pos2 = version_low_can.find(".");
50     int main_value_version_low_can = std::stoi(version_low_can.substr(0,pos2));
51
52     if(main_value_version_file != main_value_version_low_can) // Not same version
53     {
54         if(decoder_t::decoders_states_[decoder] == states::NEW)
55         {
56             if(main_value_version_low_can == 2)
57             {
58                 if(main_value_version_file == 1)
59                 {
60                     decoder_t::v1_to_v2(decoder); // add wrap
61                 }
62                 else
63                 {
64                     throw "Version not implemented";
65                 }
66             }
67             else
68             {
69                 throw "Version not implemented";
70             }
71         }
72         return decoder_t::generate_name_decoder(decoder,version_file,version_low_can);
73     }
74     else
75     {
76         return decoder;
77     }
78 }
79
80 std::string decoder_t::generate_name_decoder(std::string decoder, std::string version_file, std::string version_low_can)
81 {
82     std::size_t pos = version_file.find(".");
83     std::string main_value_version_file = version_file.substr(0,pos);
84     std::size_t pos2 = version_low_can.find(".");
85     std::string main_value_version_low_can = version_low_can.substr(0,pos2);
86     return "v"+main_value_version_file+"_to_v"+main_value_version_low_can+"_"+decoder;
87 }
88
89 std::string decoder_t::apply_patch()
90 {
91     return decoder_t::patchs_;
92 }
93
94 void decoder_t::v1_to_v2(std::string decoder)
95 {
96     std::string patch = "";
97     patch = patch + "openxc_DynamicField decoder_t::v1_to_v2_"+decoder+"(signal_t& signal, std::shared_ptr<message_t> message, bool* send){\n";
98     patch = patch + "\tfloat value = decoder_t::parse_signal_bitfield(signal, message);\n";
99     patch = patch + "\topenxc_DynamicField ret = decoder_t::"+decoder+"(signal, value, send);\n";
100     patch = patch + "\tif ((signal.get_last_value() == value && !signal.get_send_same()) || !*send ){\n";
101     patch = patch + "\t\t*send = false;\n";
102     patch = patch + "\t}\n";
103     patch = patch + "\tsignal.set_last_value(value);\n";
104     patch = patch + "\treturn ret;\n";
105     patch = patch + "}\n";
106
107     decoder_t::patchs_ = decoder_t::patchs_ + "\n" + patch;
108 }