2 * State assistance routines.
3 * (C) May 16 2018 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4 * License: GPLv2 (or later)
6 * 1. Decl. state entries per device.
7 * #define STATE_VERSION n;
8 * void foo::decl_state(void)
10 * state_entry = new csp_state_utils(STATE_VERSION, this_device_id, _T("NAME")); // Must be.
11 * DECL_STATE_ENTRY(var1)
12 * DECL_STATE_ENTRY_MULTI(array, sizeof(array));
14 * 2. Call decl_state() from VM's decl_state().
16 * void foo::save_state(FILEIO *state_fio)
18 * if(state_entry != NULL) state_entry->save_state(state_fio, NULL); // Arg2 is pointer of initial CRC value.
20 * bool foo::load_state(FILEIO *state_fio)
22 * if(state_entry != NULL) return state_entry->load_state(state_fio, NULL); // Arg2 is pointer of initial CRC value.
28 #if !defined(_CSP_STATE_SUB_H)
29 #define _CSP_STATE_SUB_H
36 #include "state_data.h"
39 csp_saver_entry_int = 0,
40 csp_saver_entry_uint8,
42 csp_saver_entry_uint16,
43 csp_saver_entry_int16,
44 csp_saver_entry_uint32,
45 csp_saver_entry_int32,
46 csp_saver_entry_uint64,
47 csp_saver_entry_int64,
49 csp_saver_entry_tchar,
51 csp_saver_entry_float,
52 csp_saver_entry_double,
53 csp_saver_entry_long_double,
57 csp_saver_entry_cur_time_t,
59 csp_saver_entry_custom0 = 256,
60 csp_saver_entry_custom1 = 257,
61 csp_saver_entry_custom2 = 258,
62 csp_saver_entry_custom3 = 259,
64 // Below are special value
65 csp_saver_entry_vararray = 0x10000,
66 csp_saver_entry_const = 0x20000,
71 class DLL_PREFIX csp_state_utils {
74 const uint32_t CRC_MAGIC_WORD = 0x04C11DB7;
85 std::list<__list_t>listptr;
86 _TCHAR __classname[128];
87 _TCHAR __classname_bak[128];
93 int class_version_bak;
95 int internal_version_bak;
97 int this_device_id_bak;
98 csp_state_data_saver *fio;
100 void out_debug_log(const char *fmt, ...);
102 csp_state_utils(int _version = 1, int device_id = 1, const _TCHAR *classname = NULL, CSP_Logger* p_logger = NULL);
104 std::list<std::string> get_entries_list(void);
107 void add_entry(const _TCHAR *__name, T *p, int _len = 1, int __num = -1, bool is_const = false)
110 std::string _name = std::string(__name);
111 if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
113 _l.type_id = csp_saver_entry_any;
115 _l.atomlen = sizeof(T);
117 _l.datalenptr = NULL;
118 _l.local_num = __num;
119 _l.assume_byte = false;
120 out_debug_log("ADD ENTRY: NAME=%s TYPE=%s len=%d atomlen=%d", _name.c_str(), typeid(T).name(), _len, _l.atomlen);
121 if(typeid(T) == typeid(int)) {
122 _l.type_id = csp_saver_entry_int;
123 } else if(typeid(T) == typeid(pair_t)) {
124 _l.type_id = csp_saver_entry_pair;
125 } else if(typeid(T) == typeid(float)) {
126 _l.type_id = csp_saver_entry_float;
127 } else if(typeid(T) == typeid(double)) {
128 _l.type_id = csp_saver_entry_double;
129 } else if(typeid(T) == typeid(long double)) {
130 _l.type_id = csp_saver_entry_long_double;
131 } else if(typeid(T) == typeid(int8_t)) {
132 _l.type_id = csp_saver_entry_int8;
133 } else if(typeid(T) == typeid(uint8_t)) {
134 _l.type_id = csp_saver_entry_uint8;
135 } else if(typeid(T) == typeid(int16_t)) {
136 _l.type_id = csp_saver_entry_int16;
137 } else if(typeid(T) == typeid(uint16_t)) {
138 _l.type_id = csp_saver_entry_uint16;
139 } else if(typeid(T) == typeid(int32_t)) {
140 _l.type_id = csp_saver_entry_int32;
141 } else if(typeid(T) == typeid(uint32_t)) {
142 _l.type_id = csp_saver_entry_uint32;
143 } else if(typeid(T) == typeid(int64_t)) {
144 _l.type_id = csp_saver_entry_int64;
145 } else if(typeid(T) == typeid(uint64_t)) {
146 _l.type_id = csp_saver_entry_uint64;
147 } else if(typeid(T) == typeid(bool)) {
148 _l.type_id = csp_saver_entry_bool;
151 if(is_const) _l.type_id = _l.type_id | csp_saver_entry_const;
152 listptr.push_back(_l);
155 void add_entry_vararray(const _TCHAR *__name, T **p, void *datalen, bool assume_byte = false, int __num = -1)
159 if(datalen == NULL) {
160 add_entry(__name, p, 1);
163 std::string _name = std::string(__name);
164 if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
169 _l.atomlen = sizeof(T);
171 _l.local_num = __num;
172 _l.datalenptr = (int *) datalen;
173 _l.assume_byte = assume_byte;
174 if(typeid(T) == typeid(int)) {
175 _l.type_id = csp_saver_entry_int;
176 } else if(typeid(T) == typeid(pair_t)) {
177 _l.type_id = csp_saver_entry_pair;
178 } else if(typeid(T) == typeid(float)) {
179 _l.type_id = csp_saver_entry_float;
180 } else if(typeid(T) == typeid(double)) {
181 _l.type_id = csp_saver_entry_double;
182 } else if(typeid(T) == typeid(long double)) {
183 _l.type_id = csp_saver_entry_long_double;
184 } else if(typeid(T) == typeid(int8_t)) {
185 _l.type_id = csp_saver_entry_int8;
186 } else if(typeid(T) == typeid(uint8_t)) {
187 _l.type_id = csp_saver_entry_uint8;
188 } else if(typeid(T) == typeid(int16_t)) {
189 _l.type_id = csp_saver_entry_int16;
190 } else if(typeid(T) == typeid(uint16_t)) {
191 _l.type_id = csp_saver_entry_uint16;
192 } else if(typeid(T) == typeid(int32_t)) {
193 _l.type_id = csp_saver_entry_int32;
194 } else if(typeid(T) == typeid(uint32_t)) {
195 _l.type_id = csp_saver_entry_uint32;
196 } else if(typeid(T) == typeid(int64_t)) {
197 _l.type_id = csp_saver_entry_int64;
198 } else if(typeid(T) == typeid(uint64_t)) {
199 _l.type_id = csp_saver_entry_uint64;
200 } else if(typeid(T) == typeid(bool)) {
201 _l.type_id = csp_saver_entry_bool;
203 _l.type_id = _l.type_id | csp_saver_entry_vararray;
204 out_debug_log("ADD ENTRY(VARARRAY): NAME=%s TYPE=%s atomlen=%d linked len=%08x", __name, typeid(T).name(), _l.atomlen, datalen);
205 listptr.push_back(_l);
208 void add_entry_fifo(const _TCHAR *__name, FIFO **p, int _len = 1, int __num = -1);
209 void add_entry_cur_time_t(const _TCHAR *__name, cur_time_t *p, int _len = 1, int __num = -1);
210 void add_entry_tchar(const _TCHAR *__name, _TCHAR *p, int _len = 1, int __num = -1, bool is_const = false);
212 uint32_t get_crc_value(void);
213 void get_class_name(_TCHAR *buf, int len);
214 bool save_state(FILEIO *__fio, uint32_t *pcrc = NULL);
215 bool load_state(FILEIO *__fio, uint32_t *pcrc = NULL);
219 #define DECL_STATE_ENTRY0(_n_name, __list) { \
220 __list->add_entry((const _TCHAR *)_T(#_n_name), &_n_name); \
223 #define DECL_STATE_ENTRY1(_n_name, __list, __len) { \
224 __list->add_entry((const _TCHAR *)_T(#_n_name), _n_name, __len); \
227 #define DECL_STATE_ENTRY2(_n_name, __list, __len, __n) { \
228 __list->add_entry((const _TCHAR *)_T(#_n_name), &_n_name, __len, __n); \
231 #define DECL_STATE_ENTRY_MULTI0(__type, _n_name, __list, __size) { \
232 __list->add_entry((const _TCHAR *)_T(#_n_name), (uint8_t *)_n_name, __size * sizeof(__type)); \
235 #define DECL_STATE_ENTRY_INT(___name) DECL_STATE_ENTRY0(___name, state_entry)
237 #define DECL_STATE_ENTRY_UINT8(___name) DECL_STATE_ENTRY0(___name, state_entry)
238 #define DECL_STATE_ENTRY_INT8(___name) DECL_STATE_ENTRY0(___name, state_entry)
239 #define DECL_STATE_ENTRY_UINT16(___name) DECL_STATE_ENTRY0(___name, state_entry)
240 #define DECL_STATE_ENTRY_INT16(___name) DECL_STATE_ENTRY0(___name, state_entry)
241 #define DECL_STATE_ENTRY_UINT32(___name) DECL_STATE_ENTRY0(___name, state_entry)
242 #define DECL_STATE_ENTRY_INT32(___name) DECL_STATE_ENTRY0(___name, state_entry)
243 #define DECL_STATE_ENTRY_UINT64(___name) DECL_STATE_ENTRY0( ___name, state_entry)
244 #define DECL_STATE_ENTRY_INT64(___name) DECL_STATE_ENTRY0(___name, state_entry)
245 #define DECL_STATE_ENTRY_PAIR(___name) DECL_STATE_ENTRY0(___name, state_entry)
246 #define DECL_STATE_ENTRY_BOOL(___name) DECL_STATE_ENTRY0(___name, state_entry)
247 #define DECL_STATE_ENTRY_TCHAR(___name) DECL_STATE_ENTRY0(___name, state_entry)
248 #define DECL_STATE_ENTRY_FLOAT(___name) DECL_STATE_ENTRY0(___name, state_entry)
249 #define DECL_STATE_ENTRY_DOUBLE(___name) DECL_STATE_ENTRY0(___name, state_entry)
250 #define DECL_STATE_ENTRY_LONG_DOUBLE(___name) DECL_STATE_ENTRY0(___name, state_entry)
252 #define DECL_STATE_ENTRY_UINT8_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
253 #define DECL_STATE_ENTRY_INT8_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
254 #define DECL_STATE_ENTRY_UINT16_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
255 #define DECL_STATE_ENTRY_INT16_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
256 #define DECL_STATE_ENTRY_UINT32_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
257 #define DECL_STATE_ENTRY_INT32_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
258 #define DECL_STATE_ENTRY_UINT64_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
259 #define DECL_STATE_ENTRY_INT64_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
260 #define DECL_STATE_ENTRY_BOOL_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
261 #define DECL_STATE_ENTRY_PAIR_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
262 #define DECL_STATE_ENTRY_FLOAT_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
263 #define DECL_STATE_ENTRY_DOUBLE_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
264 #define DECL_STATE_ENTRY_LONG_DOUBLE_ARRAY(___name, __len) DECL_STATE_ENTRY1(___name, state_entry, __len)
266 #define DECL_STATE_ENTRY_UINT8_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
267 #define DECL_STATE_ENTRY_INT8_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
268 #define DECL_STATE_ENTRY_UINT16_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
269 #define DECL_STATE_ENTRY_INT16_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
270 #define DECL_STATE_ENTRY_UINT32_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
271 #define DECL_STATE_ENTRY_INT32_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
272 #define DECL_STATE_ENTRY_UINT64_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
273 #define DECL_STATE_ENTRY_INT64_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
274 #define DECL_STATE_ENTRY_BOOL_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
275 #define DECL_STATE_ENTRY_PAIR_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
276 #define DECL_STATE_ENTRY_UINT8_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
277 #define DECL_STATE_ENTRY_FLOAT_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
278 #define DECL_STATE_ENTRY_DOUBLE_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
279 #define DECL_STATE_ENTRY_LONG_DOUBLE_MEMBER(___name, __num) DECL_STATE_ENTRY2(___name, state_entry, 1, __num)
283 #define DECL_STATE_ENTRY_MULTI(_n_type, ___name, ___size) DECL_STATE_ENTRY_MULTI0(_n_type, ___name, state_entry, ___size)
285 #define DECL_STATE_ENTRY_STRING(___name, __len) { \
286 state_entry->add_entry_tchar((_TCHAR *)(_T(#___name)), ___name, __len); \
289 #define DECL_STATE_ENTRY_STRING_MEMBER(___name, __len, __num) { \
290 state_entry->add_entry_tchar((_TCHAR *)(_T(#___name)), ___name, __len, __num); \
293 #define DECL_STATE_ENTRY_1D_ARRAY(___name, ___lenvar) { \
294 state_entry->add_entry((const _TCHAR *)(_T(#___name)), ___name, ___lenvar); \
297 #define DECL_STATE_ENTRY_2D_ARRAY(___name, __len1, __len2) { \
298 int __tmplen = ((int)__len1 * (int)__len2); \
299 state_entry->add_entry((const _TCHAR *)(_T(#___name)), &(___name[0][0]), __tmplen); \
302 #define DECL_STATE_ENTRY_3D_ARRAY(___name, __len1, __len2, __len3) { \
303 int __tmplen = ((int)__len1 * (int)__len2 * (int)__len3); \
304 state_entry->add_entry((const _TCHAR *)_T(#___name), &(___name[0][0][0]), __tmplen); \
307 #define DECL_STATE_ENTRY_4D_ARRAY(___name, __len1, __len2, __len3, __len4) { \
308 int __tmplen = ((int)__len1 * (int)__len2 * (int)__len3 * (int)__len4); \
309 state_entry->add_entry((const _TCHAR *)_T(#___name), &(___name[0][0][0][0]), __tmplen); \
312 #define DECL_STATE_ENTRY_1D_ARRAY_MEMBER(___name, ___lenvar, __num) { \
313 state_entry->add_entry((const _TCHAR *)(_T(#___name)), ___name, ___lenvar, __num); \
316 #define DECL_STATE_ENTRY_2D_ARRAY_MEMBER(___name, __len1, __len2, __num) { \
317 int __tmplen = ((int)__len1 * (int)__len2); \
318 state_entry->add_entry((const _TCHAR *)(_T(#___name)), &(___name[0][0]), __tmplen, __num); \
321 #define DECL_STATE_ENTRY_3D_ARRAY_MEMBER(___name, __len1, __len2, __len3, __num) { \
322 int __tmplen = ((int)__len1 * (int)__len2 * (int)__len3); \
323 state_entry->add_entry((const _TCHAR *)_T(#___name), &(___name[0][0][0]), __tmplen, __num); \
326 #define DECL_STATE_ENTRY_VARARRAY_VAR(_n_name, __sizevar) { \
327 state_entry->add_entry_vararray((const _TCHAR *)_T(#_n_name), &_n_name, (void *)(&__sizevar)); \
330 #define DECL_STATE_ENTRY_VARARRAY_MEMBER(_n_name, __sizevar, __n) { \
331 state_entry->add_entry_vararray((const _TCHAR *)_T(#_n_name), &_n_name, (void *)(&__sizevar), false, __n); \
334 #define DECL_STATE_ENTRY_VARARRAY_BYTES(_n_name, __sizevar) { \
335 state_entry->add_entry_vararray((const _TCHAR *)_T(#_n_name), &_n_name, (void *)(&__sizevar), true); \
338 #define DECL_STATE_ENTRY_VARARRAY_BYTES_MEMBER(_n_name, __sizevar, __n) { \
339 state_entry->add_entry_vararray((const _TCHAR *)_T(#_n_name), &_n_name, (void *)(&__sizevar), true, __n); \
342 #define DECL_STATE_ENTRY_SINGLE(___name) { \
343 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name); \
346 #define DECL_STATE_ENTRY_SINGLE_MEMBER(___name, __num) { \
347 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name, 1, __num); \
350 #define DECL_STATE_ENTRY_SINGLE_ARRAY(___name, __len) { \
351 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name, __len); \
353 #define DECL_STATE_ENTRY_SINGLE_ARRAY_MEMBER(___name, __len, __num) { \
354 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name, __len, __num); \
357 #define DECL_STATE_ENTRY_FIFO(_n_name) { \
358 state_entry->add_entry_fifo((const _TCHAR *)_T(#_n_name), &_n_name, 1); \
361 #define DECL_STATE_ENTRY_FIFO_ARRAY(_n_name, __len) { \
362 state_entry->add_entry_fifo((const _TCHAR *)_T(#_n_name), &_n_name, __len); \
365 #define DECL_STATE_ENTRY_FIFO_MEMBER(_n_name, __n) { \
366 state_entry->add_entry_fifo((const _TCHAR *)_T(#_n_name), &_n_name, 1, __n); \
369 #define DECL_STATE_ENTRY_FIFO_ARRAY_MEMBER(_n_name, __len, __n) { \
370 state_entry->add_entry_fifo((const _TCHAR *)_T(#_n_name), &_n_name, __len, __n); \
373 #define DECL_STATE_ENTRY_CUR_TIME_T(_n_name) { \
374 state_entry->add_entry_cur_time_t((const _TCHAR *)_T(#_n_name), &_n_name, 1); \
377 #define DECL_STATE_ENTRY_CUR_TIME_T_ARRAY(_n_name, __len) { \
378 state_entry->add_entry_cur_time_t((const _TCHAR *)_T(#_n_name), &_n_name, __len); \
381 #define DECL_STATE_ENTRY_CUR_TIME_T_MEMBER(_n_name, __n) { \
382 state_entry->add_entry_cur_time_t((const _TCHAR *)_T(#_n_name), &_n_name, 1, __n); \
385 #define DECL_STATE_ENTRY_CUR_TIME_T_ARRAY_MEMBER(_n_name, __len, __n) { \
386 state_entry->add_entry_cur_time_t((const _TCHAR *)_T(#_n_name), &_n_name, __len, __n); \
390 #endif /* _CSP_STATE_SUB_H */