OSDN Git Service

[VM][I386] Apply new state framework (only within libcpu_newdev).
[csp-qt/common_source_project-fm7.git] / source / src / statesub.h
1 /*
2  * State assistance routines.
3  * (C) May 16 2018 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  * License: GPLv2 (or later)
5  * Usage:
6  * 1. Decl. state entries per device.
7  *  #define STATE_VERSION n;
8  *    void foo::decl_state(void)
9  *    {
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));
13  *    }
14  * 2. Call decl_state() from VM's decl_state().
15  * 3.
16  * void foo::save_state(FILEIO *state_fio)
17  * {
18  *    if(state_entry != NULL) state_entry->save_state(state_fio, NULL); // Arg2 is pointer of initial CRC value.
19  * }
20  * bool foo::load_state(FILEIO *state_fio)
21  * {
22  *    if(state_entry != NULL) return state_entry->load_state(state_fio, NULL); // Arg2 is pointer of initial CRC value.
23  *    return false;
24  * }
25  */
26
27
28 #if !defined(_CSP_STATE_SUB_H)
29 #define _CSP_STATE_SUB_H
30 #include "common.h"
31 #include "fileio.h"
32
33
34 #include <string>
35 #include <list>
36 #include "state_data.h"
37
38 enum {
39         csp_saver_entry_int = 0,
40         csp_saver_entry_uint8,
41         csp_saver_entry_int8,
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,
48         csp_saver_entry_bool,
49         csp_saver_entry_tchar,
50         csp_saver_entry_pair,
51         csp_saver_entry_float,
52         csp_saver_entry_double,
53         csp_saver_entry_long_double,
54         csp_saver_entry_any,
55         
56         csp_saver_entry_fifo,
57         csp_saver_entry_cur_time_t,
58         
59         csp_saver_entry_custom0 = 256,
60         csp_saver_entry_custom1 = 257,
61         csp_saver_entry_custom2 = 258,
62         csp_saver_entry_custom3 = 259,
63         
64         // Below are special value
65         csp_saver_entry_vararray = 0x10000,
66         csp_saver_entry_const = 0x20000,
67 };
68
69
70 class CSP_Logger;
71 class DLL_PREFIX csp_state_utils {
72 protected:
73         CSP_Logger *logger;
74         const uint32_t CRC_MAGIC_WORD = 0x04C11DB7;
75         struct __list_t {
76                 int type_id;
77                 int local_num;
78                 bool assume_byte;
79                 int len;
80                 int atomlen;
81                 std::string name;
82                 void *ptr;
83                 int *datalenptr;
84         };
85         std::list<__list_t>listptr;
86         _TCHAR __classname[128];
87         _TCHAR __classname_bak[128];
88         
89         uint32_t crc_value;
90         _TCHAR magic[16];
91         _TCHAR magic_bak[16];
92         int class_version;
93         int class_version_bak;
94         int internal_version;
95         int internal_version_bak;
96         int this_device_id;
97         int this_device_id_bak;
98         csp_state_data_saver *fio;
99
100         void out_debug_log(const char *fmt, ...);
101 public:
102         csp_state_utils(int _version = 1, int device_id = 1, const _TCHAR *classname = NULL, CSP_Logger* p_logger = NULL);
103         ~csp_state_utils();
104         std::list<std::string> get_entries_list(void);
105
106         template <class T>
107         void add_entry(const _TCHAR *__name, T *p, int _len = 1, int __num = -1, bool is_const = false)
108         {
109                 __list_t _l;
110                 std::string _name = std::string(__name);
111                 if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
112                 _l.ptr = (void *)p;
113                 _l.type_id = csp_saver_entry_any;
114                 _l.len = _len;
115                 _l.atomlen = sizeof(T);
116                 _l.name = _name;
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;
149                 }
150
151                 if(is_const) _l.type_id = _l.type_id | csp_saver_entry_const;
152                 listptr.push_back(_l);
153         };
154         template <class T>
155         void add_entry_vararray(const _TCHAR *__name, T **p, void *datalen, bool assume_byte = false, int __num = -1)
156         {
157                 __list_t _l;
158                 
159                 if(datalen == NULL) {
160                         add_entry(__name, p, 1);
161                         return;
162                 }
163                 std::string _name = std::string(__name);
164                 if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
165                 
166                 _l.ptr = (void *)p;
167                 _l.type_id = 0;
168                 _l.len = 0;
169                 _l.atomlen = sizeof(T);
170                 _l.name = _name;
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;
202                 }
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);
206         };
207
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);
211         
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);
216 };
217         
218                         
219 #define DECL_STATE_ENTRY0(_n_name, __list) {                              \
220                 __list->add_entry((const _TCHAR *)_T(#_n_name), &_n_name);                \
221         }
222
223 #define DECL_STATE_ENTRY1(_n_name, __list, __len) {                             \
224                 __list->add_entry((const _TCHAR *)_T(#_n_name), _n_name, __len);                \
225         }
226
227 #define DECL_STATE_ENTRY2(_n_name, __list, __len, __n) {                                        \
228                 __list->add_entry((const _TCHAR *)_T(#_n_name), &_n_name, __len, __n); \
229         }
230
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)); \
233         }
234    
235 #define DECL_STATE_ENTRY_INT(___name) DECL_STATE_ENTRY0(___name, state_entry)
236
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)
251
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)
265
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)
280
281
282
283 #define DECL_STATE_ENTRY_MULTI(_n_type, ___name, ___size) DECL_STATE_ENTRY_MULTI0(_n_type, ___name, state_entry, ___size)
284
285 #define DECL_STATE_ENTRY_STRING(___name, __len) { \
286         state_entry->add_entry_tchar((_TCHAR *)(_T(#___name)), ___name, __len); \
287         }
288
289 #define DECL_STATE_ENTRY_STRING_MEMBER(___name, __len, __num) {                         \
290                 state_entry->add_entry_tchar((_TCHAR *)(_T(#___name)), ___name, __len, __num); \
291         }
292
293 #define DECL_STATE_ENTRY_1D_ARRAY(___name, ___lenvar) { \
294                 state_entry->add_entry((const _TCHAR *)(_T(#___name)), ___name, ___lenvar); \
295         }
296
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); \
300         }
301
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); \
305         }
306
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); \
310         }
311
312 #define DECL_STATE_ENTRY_1D_ARRAY_MEMBER(___name, ___lenvar, __num) {   \
313                 state_entry->add_entry((const _TCHAR *)(_T(#___name)), ___name, ___lenvar, __num); \
314         }
315
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); \
319         }
320
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); \
324         }
325
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)); \
328         }
329
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); \
332         }
333
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); \
336         }
337
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); \
340         }
341
342 #define DECL_STATE_ENTRY_SINGLE(___name) { \
343                 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name); \
344         }
345
346 #define DECL_STATE_ENTRY_SINGLE_MEMBER(___name, __num) {                                                \
347                 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name, 1, __num); \
348         }
349
350 #define DECL_STATE_ENTRY_SINGLE_ARRAY(___name, __len) {                                         \
351                 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name, __len); \
352         }
353 #define DECL_STATE_ENTRY_SINGLE_ARRAY_MEMBER(___name, __len, __num) {                   \
354                 state_entry->add_entry((const _TCHAR *)_T(#___name) , &___name, __len, __num); \
355         }
356
357 #define DECL_STATE_ENTRY_FIFO(_n_name) {                                                                \
358                 state_entry->add_entry_fifo((const _TCHAR *)_T(#_n_name), &_n_name, 1); \
359         }
360
361 #define DECL_STATE_ENTRY_FIFO_ARRAY(_n_name, __len) {                                   \
362                 state_entry->add_entry_fifo((const _TCHAR *)_T(#_n_name), &_n_name, __len); \
363         }
364
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); \
367         }
368
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); \
371         }
372    
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); \
375         }
376
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); \
379         }
380
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); \
383         }
384
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); \
387         }
388
389
390 #endif /* _CSP_STATE_SUB_H */