Aufgrund einer Wartung wird GitLab am 21.09. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 21.09. between 8:00 and 9:00 am.

Commit 5fd91f60 authored by Jean Meurice's avatar Jean Meurice
Browse files

Move to shared_cpp submodule

parent be6419e3
#include "basic_interface.h"
using namespace std;
/*
INTERFACE STRING
*/
string BASIC_INTERFACE = string(R"(
{
"name":"basic_interface",
"version":"1.0",
"ports":[
{"name":"true_velocity","type":{"type":"basic","base_type":"Q"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"true_position","type":{"type":"basic","base_type":"vec2"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"true_compass","type":{"type":"basic","base_type":"Q"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"trajectory_length","type":{"type":"basic","base_type":"N"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"trajectory_x","type":{"type":"vector","base_type":{"type":"basic","base_type":"Q"},"size":10},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"trajectory_y","type":{"type":"vector","base_type":{"type":"basic","base_type":"Q"},"size":10},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"steering","type":{"type":"basic","base_type":"Q"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"gas","type":{"type":"basic","base_type":"Q"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"braking","type":{"type":"basic","base_type":"Q"},"direction":"INPUT","allows_multiple_inputs":false,"optional":false},
{"name":"set_steering","type":{"type":"basic","base_type":"Q"},"direction":"OUTPUT","allows_multiple_inputs":false,"optional":false},
{"name":"set_gas","type":{"type":"basic","base_type":"Q"},"direction":"OUTPUT","allows_multiple_inputs":false,"optional":false},
{"name":"set_braking","type":{"type":"basic","base_type":"Q"},"direction":"OUTPUT","allows_multiple_inputs":false,"optional":false}
]
}
)");
\ No newline at end of file
#pragma once
#include <string>
#define BASIC_INTERFACE_INPUT_COUNT 9
#define BASIC_INTERFACE_OUTPUT_COUNT 3
#define BASIC_INTERFACE_PORT_COUNT (BASIC_INTERFACE_INPUT_COUNT+BASIC_INTERFACE_OUTPUT_COUNT)
extern std::string BASIC_INTERFACE;
#define PORT_TRUE_VELOCITY 0
#define PORT_TRUE_POSITION 1
#define PORT_TRUE_COMPASS 2
#define PORT_TRAJ_LENGTH 3
#define PORT_TRAJ_X 4
#define PORT_TRAJ_Y 5
#define PORT_STEERING 6
#define PORT_GAS 7
#define PORT_BRAKING 8
#define PORT_SET_STEERING 9
#define PORT_SET_GAS 10
#define PORT_SET_BRAKING 11
\ No newline at end of file
#pragma once
constexpr int MIN_DDC_ID = 0x4000;
constexpr int DDC_MAX_LENGTH = 195;
constexpr int ID_RUNNING = 0;
constexpr int ID_INTERFACE_TYPE = 1;
constexpr int ID_TIME_MODE = 2;
constexpr int ID_RUN_CYCLE_SWITCH = 3;
constexpr int ID_DELTA_SEC = 4;
constexpr int ID_EXEC_TIME = 5;
constexpr int ID_SIM_RUNNING = 6;
constexpr int ID_INPUT_START_ID = 7;
constexpr int ID_OUTPUT_START_ID = 8;
constexpr int ID_SLOT_TABLE_START = 7;
constexpr int ID_INTERFACE_STRING_COUNT = 8;
constexpr int ID_INTERFACE_STRING = 9;
\ No newline at end of file
/** (c) https://github.com/MontiCore/monticore */
#include "dynamic_interface.h"
#include "json.h"
#include "./${mainModelName}.h"
${mainModelName} program_instance;
JsonWriter writer;
extern "C" {
EXPORT const char* DI__get_interface() {
return R"(
${interfaceDescription}
)";
}
EXPORT void DI__set_port(int i, const char* data) {
JsonTraverser traverser;
traverser.init(data);
switch(i){
<#list setPortCases as setPortCase>
${setPortCase}
</#list>
}
}
EXPORT const char* DI__get_port(int i) {
writer.init();
switch (i){
<#list getPortCases as getPortCase>
${getPortCase}
</#list>
}
return writer.get_string();
}
// Methods
EXPORT void DI__init() {
writer.format = false;
srand(time(NULL));
program_instance.init();
}
EXPORT void DI__execute(double delta_sec) {
// TODO set "delta_sec" port ?
program_instance.execute();
}
}
\ No newline at end of file
/** (c) https://github.com/MontiCore/monticore */
#pragma once
#if defined(_MSC_VER)
// Microsoft
#define EXPORT __declspec(dllexport)
#define IMPORT __declspec(dllimport)
#elif defined(__GNUC__)
// GCC
#define EXPORT __attribute__((visibility("default")))
#define IMPORT
#else
// do nothing and hope for the best?
#define EXPORT
#define IMPORT
#pragma warning Unknown dynamic link import/export semantics.
#endif
extern "C" {
// Returns a JSON string deserializable to the ProgramInterface class (Commons).
EXPORT const char* DI__get_interface();
EXPORT void DI__set_port(int i, const char* data);
EXPORT const char* DI__get_port(int i);
// Methods
EXPORT void DI__init();
EXPORT void DI__execute(double delta_sec);
}
/**
* (c) https://github.com/MontiCore/monticore
*/
#include "json.h"
//#include <cstdio>
#include <math.h>
#include <cctype>
#include <limits>
#include <sstream>
#include "printf.h"
//#include <float.h>
char JsonWriter::LOCAL_BUFFER[JsonWriter::LOCAL_BUFFER_SIZE];
void JsonWriter::init(){
if (buffer == nullptr) {
alloc();
}
offset = 0;
pos = 0;
has_elem = false;
has_key = true;
}
void JsonWriter::alloc(){
buffer = new char[START_BUFFER_SIZE];
buffer_size = START_BUFFER_SIZE;
pos = 0;
}
void JsonWriter::append(const char c) {
buffer[pos] = c;
++pos;
if (pos >= buffer_size) {
int32_t new_size = buffer_size + START_BUFFER_SIZE;
char *new_buff = new char[new_size];
for (int32_t i = 0; i < buffer_size; ++i){
new_buff[i] = buffer[i];
}
delete[] buffer;
buffer = new_buff;
buffer_size = new_size;
}
}
void JsonWriter::append(const char* str){
int32_t i = 0;
while (str[i]){
append(str[i]); ++i;
}
}
const char* JsonWriter::get_string() {
if (buffer == nullptr) {
alloc();
}
buffer[pos] = '\0';
return buffer;
}
void JsonWriter::start_object() {
separate();
if (format) offset += TAB;
append('{');
has_elem = false;
}
void JsonWriter::add_offset(){
for (int32_t i = 0; i < offset; ++i){
append(' ');
}
}
void JsonWriter::end_object() {
if (format) {
offset -= TAB;
if (has_elem){
append('\n');
add_offset();
}
}
append('}');
has_elem = true;
}
void JsonWriter::start_array() {
separate();
if (format) offset += TAB;
append('[');
has_elem = false;
}
void JsonWriter::end_array() {
if (format) {
offset -= TAB;
if (has_elem){
append('\n');
add_offset();
}
}
append(']');
has_elem = true;
}
void JsonWriter::separate() {
if (has_elem && !has_key) append(',');
else has_elem = true;
if (!has_key) {
if (format) {
append('\n');
add_offset();
}
}
else has_key = false;
}
void JsonWriter::write_key(const char* key) {
write_value(key);
has_key = true;
if (format) append(": ");
else append(':');
}
void JsonWriter::write_value(const char* str) {
separate();
append('"');
int32_t i = 0;
while (str[i]){
char c = str[i];
switch(c) {
case '\n': append("\\n"); break;
case '\t': append("\\t"); break;
case '\r': append("\\r"); break;
case '\f': append("\\f"); break;
case '\b': append("\\b"); break;
case '"': append("\\\""); break;
case '/': append("\\/"); break;
case '\\': append("\\\\"); break;
default: append(c); break;
}
++i;
}
append('"');
}
void JsonWriter::write_value(int32_t i){
separate();
snprintf(LOCAL_BUFFER, LOCAL_BUFFER_SIZE, "%d", i);
append(LOCAL_BUFFER);
}
void JsonWriter::write_value(int64_t l){
separate();
snprintf(LOCAL_BUFFER, LOCAL_BUFFER_SIZE, "%lld", l);
append(LOCAL_BUFFER);
}
void JsonWriter::write_value(double d){
separate();
if (isnan(d)) append("\"NaN\"");
else if (isinf(d)) {
if (d < 0) append("\"-Infinity\"");
else append("\"Infinity\"");
}
else {
snprintf(LOCAL_BUFFER, LOCAL_BUFFER_SIZE, "%.*e", 17, d);
append(LOCAL_BUFFER);
}
}
void JsonWriter::write_value(float d){
separate();
if (isnan(d)) append("\"NaN\"");
else if (isinf(d)) {
if (d < 0) append("\"-Infinity\"");
else append("\"Infinity\"");
}
else {
snprintf(LOCAL_BUFFER, LOCAL_BUFFER_SIZE, "%.*e", 9, (double)d); //#define FLT_DECIMAL_DIG 9
append(LOCAL_BUFFER);
}
}
void JsonWriter::write_value(bool b){
separate();
if(b) {
append("true");
} else {
append("false");
}
}
bool StringRef::equals(const char* str) const {
for (int32_t i = 0; i < length; i++) {
char c = str[i];
if (c == '\0') return false;
if (start[i] != c) {
return false;
}
}
return str[length] == '\0';
}
std::string StringRef::get_json_string() const {
std::stringstream res;
for (int32_t i = 0; i < length; ++i){
auto c = start[i];
if (c == '\\' && i + 1 < length){
++i;
c = start[i];
switch(c){
case 'n': res << ('\n'); break;
case 't': res << ('\t'); break;
case 'r': res << ('\r'); break;
case 'f': res <<('\f'); break;
case 'b': res <<('\b'); break;
default: res << (c); break;
}
} else res << c;
}
return res.str();
}
ObjectIterator::ObjectIterator(JsonTraverser &traverser, int32_t iteration_depth) : traverser(traverser), iteration_depth(iteration_depth), last_elem_pos(traverser.pos) {}
ObjectIterator::ObjectIterator(JsonTraverser &traverser) : traverser(traverser), iteration_depth(-1), last_elem_pos(traverser.pos) {} // For "end()" it.
ObjectIterator& ObjectIterator::operator++() {
if (last_elem_pos == traverser.pos) {
traverser.skip_value(); // The last value was not traversed
}
while(traverser.depth > iteration_depth){
// Skip elems until back to this iterator's depth
traverser.skip_value();
}
return *this;
}
StringRef ObjectIterator::operator*() {
// Get key
if (traverser.current_type != ValueType::STRING) throw ParsingException("Parsing exception: Expected a string as key");
auto key = traverser.get_string();
last_elem_pos = traverser.pos; // Track traversal
return key;
}
bool ObjectIterator::operator !=( const ObjectIterator& other ) {
if (iteration_depth >= 0) {
return traverser.depth >= iteration_depth;
} else {
return traverser.depth >= other.iteration_depth;
}
}
ArrayIterator::ArrayIterator(JsonTraverser &traverser, int32_t iteration_depth) : traverser(traverser), iteration_depth(iteration_depth), last_elem_pos(traverser.pos) {}
ArrayIterator::ArrayIterator(JsonTraverser &traverser) : traverser(traverser), iteration_depth(-1), last_elem_pos(traverser.pos) {} // For "end()" it.
ArrayIterator& ArrayIterator::operator++() {
if (last_elem_pos == traverser.pos) {
traverser.skip_value(); // The last value was not traversed
}
while(traverser.depth > iteration_depth){
// Skip elems until back to this iterator's depth
traverser.skip_value();
}
last_elem_pos = traverser.pos; // Track traversal
return *this;
}
ValueType ArrayIterator::operator*() {
return traverser.current_type;
}
bool ArrayIterator::operator!=( const ArrayIterator& other ) {
if (iteration_depth >= 0) {
return traverser.depth >= iteration_depth;
} else {
return traverser.depth >= other.iteration_depth;
}
}
void JsonTraverser::init(const char *data) {
pos = data;
c = *pos;
depth = 0;
goto_next_value();
}
bool JsonTraverser::is_empty(){
if (current_type == ValueType::OBJECT){
return next_non_ws() == '}';
} else if (current_type == ValueType::ARRAY) {
return next_non_ws() == ']';
} else return false;
}
ObjectStream JsonTraverser::stream_object() {
// TODO
if (current_type != ValueType::OBJECT) throw ParsingException("Parsing exception: tried to read object but got wrong type.");
next_char(); // Move after '{'
depth++;
int32_t iteration_depth = depth;
goto_next_value();
return ObjectStream(*this, iteration_depth);
}
ArrayStream JsonTraverser::stream_array() {
// TODO
if (current_type != ValueType::ARRAY) throw ParsingException("Parsing exception: tried to read array but got wrong type.");
next_char(); // Move after '['
depth++;
int32_t iteration_depth = depth;
goto_next_value();
return ArrayStream(*this, iteration_depth);
}
bool JsonTraverser::get_bool() {
if (current_type != ValueType::BOOLEAN) throw ParsingException("Parsing exception: tried to read bool but got wrong type.");
skip_bool();
goto_next_value();
return last_bool;
}
StringRef JsonTraverser::get_string() {
if (current_type != ValueType::STRING) throw ParsingException("Parsing exception: tried to read string but got wrong type.");
auto start = pos +1;
skip_string();
auto end = pos - 1;
goto_next_value();
return StringRef(start, end - start);
}
double JsonTraverser::get_double() {
if (current_type == ValueType::NUMBER) {
char *end;
auto res = strtod(pos, &end);
goto_char(end);
goto_next_value();
return res;
} else if (current_type == ValueType::STRING) {
auto s = get_string();
if (s.equals("NaN"))
return nan(nullptr);
if (s.equals("-Infinity"))
return -std::numeric_limits<double>::infinity();
if (s.equals("Infinity"))
return std::numeric_limits<double>::infinity();
}
throw ParsingException("Parsing exception: tried to read double but got wrong type.");
}
int64_t JsonTraverser::get_long() {
if (current_type != ValueType::NUMBER) throw ParsingException("Parsing exception: tried to read int64_t but got wrong type.");
char *end;
auto res = strtoll(pos, &end, 10);
goto_char(end);
goto_next_value();
return res;
}
void JsonTraverser::expect_valid_integer(int64_t l) {
if (l > (int64_t) INT32_MAX || l < (int64_t) INT32_MIN)
throw ParsingException("Parsing exception: The int64_t doesn't fit in an int32_t");
}
void JsonTraverser::get_value_type() {
if (c == '{')
current_type = ValueType::OBJECT;
else if (c == '[')
current_type = ValueType::ARRAY;
else if (c == '"')
current_type = ValueType::STRING;
else if (c == 't' || c == 'T' || c == 'f' || c == 'F')
current_type = ValueType::BOOLEAN;
else if ((c >= '0' && c <= '9') || c == '-' || c == '+')
current_type = ValueType::NUMBER;
else
current_type = ValueType::UNKNOWN;
}
/**
* Assumes the current position is AFTER a value.
* Then skips WS and separators and goes to the next VALUE (key or value).
* Evaluates the Next Value Type.
*/
void JsonTraverser::goto_next_value() {
skip_whitespace();
if (c == ':') {
next_char();
skip_whitespace();
get_value_type();
return;
}
do {
if (c == ',') {
next_char();
skip_whitespace();
}
if (c == ']' || c == '}') {
depth--;
next_char();
skip_whitespace();
} else
break;
} while (true);
get_value_type();
}
/*
SKIP FUNCTIONS