-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathmodel.c
160 lines (121 loc) · 3.7 KB
/
model.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "config.h"
#include "model.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")
#endif
#define MAX_PATH_LENGTH 4096
void setStartValues(ModelInstance *comp) {
M(y) = 0;
}
Status calculateValues(ModelInstance *comp) {
// load the file
FILE *file = NULL;
char path[MAX_PATH_LENGTH] = "";
char c = '\0';
if (!comp->resourceLocation) {
logError(comp, "Resource location must not be NULL.");
return Error;
}
#ifdef _WIN32
#if FMI_VERSION < 3
DWORD pathLen = MAX_PATH_LENGTH;
if (PathCreateFromUrlA(comp->resourceLocation, path, &pathLen, 0) != S_OK) {
logError(comp, "Failed to convert resource location to file system path.");
return Error;
}
#else
strncpy(path, comp->resourceLocation, MAX_PATH_LENGTH);
#endif
#if FMI_VERSION == 1
if (!PathAppendA(path, "resources") || !PathAppendA(path, "y.txt")) return Error;
#elif FMI_VERSION == 2
if (!PathAppendA(path, "y.txt")) return Error;
#else
if (!strncat(path, "y.txt", MAX_PATH_LENGTH)) return Error;
#endif
#else
#if FMI_VERSION < 3
const char *scheme1 = "file:///";
const char *scheme2 = "file:/";
if (strncmp(comp->resourceLocation, scheme1, strlen(scheme1)) == 0) {
strncpy(path, &comp->resourceLocation[strlen(scheme1)] - 1, MAX_PATH_LENGTH-1);
} else if (strncmp(comp->resourceLocation, scheme2, strlen(scheme2)) == 0) {
strncpy(path, &comp->resourceLocation[strlen(scheme2) - 1], MAX_PATH_LENGTH-1);
} else {
logError(comp, "The resourceLocation must start with \"file:/\" or \"file:///\"");
return Error;
}
// decode percent encoded characters
char* src = path;
char* dst = path;
char buf[3] = { '\0', '\0', '\0' };
while (*src) {
if (*src == '%' && (buf[0] = src[1]) && (buf[1] = src[2])) {
*dst = strtol(buf, NULL, 16);
src += 3;
} else {
*dst = *src;
src++;
}
dst++;
}
*dst = '\0';
#else
strncpy(path, comp->resourceLocation, MAX_PATH_LENGTH);
#endif
#if FMI_VERSION == 1
strncat(path, "/resources/y.txt", MAX_PATH_LENGTH-strlen(path)-1);
#elif FMI_VERSION == 2
strncat(path, "/y.txt", MAX_PATH_LENGTH-strlen(path)-1);
#else
strncat(path, "y.txt", MAX_PATH_LENGTH-strlen(path)-1);
#endif
path[MAX_PATH_LENGTH-1] = 0;
#endif
// open the resource file
file = fopen (path, "r");
if (!file) {
logError(comp, "Failed to open resource file %s.", path);
return Error;
}
// read the first character
c = (char)fgetc(file);
// assign it to y
M(y) = c;
// close the file
fclose(file);
return OK;
}
Status getFloat64(ModelInstance* comp, ValueReference vr, double values[], size_t nValues, size_t* index) {
ASSERT_NVALUES(1);
switch (vr) {
case vr_time:
values[(*index)++] = comp->time;
return OK;
default:
logError(comp, "Get Float64 is not allowed for value reference %u.", vr);
return Error;
}
}
Status getInt32(ModelInstance* comp, ValueReference vr, int32_t values[], size_t nValues, size_t* index) {
ASSERT_NVALUES(1);
switch (vr) {
case vr_y:
values[(*index)++] = M(y);
return OK;
default:
logError(comp, "Get Int32 is not allowed for value reference %u.", vr);
return Error;
}
}
Status eventUpdate(ModelInstance *comp) {
comp->valuesOfContinuousStatesChanged = false;
comp->nominalsOfContinuousStatesChanged = false;
comp->terminateSimulation = false;
comp->nextEventTimeDefined = false;
return OK;
}