OSDN Git Service

[VM][I386] Apply new state framework (only within libcpu_newdev).
[csp-qt/common_source_project-fm7.git] / source / src / statesub.cpp
1
2 #include "common.h"
3 #include "fileio.h"
4 #include "fifo.h"
5
6 #include "state_data.h"
7 #include "statesub.h"
8
9 csp_state_data_saver::csp_state_data_saver(FILEIO *_fio)
10 {
11         fio = _fio;
12 }
13
14 csp_state_data_saver::~csp_state_data_saver()
15 {
16 }
17
18 size_t csp_state_data_saver::save_string_data(const _TCHAR *p, uint32_t *sumseed, int maxlen, bool *__stat)
19 {
20         size_t locallen;
21         if(__stat != NULL) *__stat =  false;
22         if(p == NULL) return -1;
23         if(maxlen <= 0) {
24                 locallen = strlen(p);
25         } else {
26                 locallen = strnlen(p, maxlen);
27         }
28         if(locallen < 0) return locallen;
29         locallen += 1; // Include "\0";
30         if(sumseed != NULL) {
31                 *sumseed = calc_crc32(*sumseed, (uint8_t *)p, locallen * sizeof(char));
32         }
33         size_t cp;
34         for(cp = 0; cp < locallen; cp++) {
35                 int _t = (int)(p[cp]);
36                 int res = fio->Fputc(_t);
37                 if((_t == '\0') || (_t == 0x00)){
38                         cp++;
39                         if(__stat != NULL) *__stat =  true;
40                         break;
41                 } else if(_t == EOF) {
42                         return (size_t)EOF; // ERROR
43                 }
44         }
45         return locallen;
46 }
47
48 size_t csp_state_data_saver::load_string_data(_TCHAR *p, uint32_t *sumseed, int maxlen, bool *__stat)
49 {
50         size_t cp;
51         size_t _nlen;
52         if(__stat != NULL) *__stat =  false;
53         if(p == NULL) return -1;
54         if(maxlen <= 0) return -1;
55         memset(p, 0x00, sizeof(_TCHAR) * maxlen);
56         for(cp = 0; cp < maxlen; cp++) {
57                 int _t = fio->Fgetc();
58                 if((_t == '\0') || (_t == 0x00)){
59                         p[cp] = 0x00;
60                         cp++;
61                         if(__stat != NULL) *__stat =  true;
62                         break;
63                 } else  if(_t == EOF) {
64                         p[cp] = 0x00;
65                         cp++;
66                         if(__stat != NULL) *__stat =  false;
67                         break;
68                 } else if((cp + 1) >= maxlen) {
69                         p[cp] = (_TCHAR)_t;
70                         if(__stat != NULL) *__stat =  true;
71                         cp++;
72                         break;
73                 }
74                 p[cp] = (_TCHAR)_t;
75         }
76         if(cp >= maxlen) {
77                 p[maxlen - 1] = '\0';
78                 cp = maxlen;
79         }
80         _nlen = (size_t)cp;
81         if(sumseed != NULL){
82                 *sumseed = calc_crc32(*sumseed, (uint8_t *)p, _nlen * sizeof(_TCHAR));
83         }
84         return _nlen;
85 }
86 // ALL OF BYNARY VALUES SHOULD BE SAVED BY BIG ENDIAN
87 int csp_state_data_saver::save_and_change_byteorder_be(uint32_t *sum, void *val, int bytes, int rep)
88 {
89         //int swapoffset = bytes;
90         int members = 0;
91         uint8_t *buf;
92         uint8_t *srcp = (uint8_t *)val;
93                 
94         if((bytes <= 0) || (rep < 1)) return 0;
95         if(val == NULL) return 0;
96         buf = (uint8_t *)malloc(bytes); // swap buffer
97         if(buf == NULL) return 0;
98         for(members = 0; members < rep; members++) {
99 #if defined(__LITTLE_ENDIAN__)
100                 int k = 0;
101                 for(int j = (bytes - 1); j >= 0; j--) {
102                         buf[j] = srcp[k];
103                         k++;
104                 }
105 #else // BIG_ENDIAN
106                 memcpy(buf, srcp, bytes);
107 #endif
108                 if(fio->Fwrite(buf, bytes, 1) != 1) {
109                         free(buf);
110                         return members;
111                 }
112                 *sum = calc_crc32(*sum, buf, bytes);
113                 srcp += bytes;
114         }
115         free(buf);
116         return members;
117 }
118
119 int csp_state_data_saver::load_and_change_byteorder_be(uint32_t *sum, void *val, int bytes, int rep)
120 {
121         //int swapoffset = bytes;
122         int members = 0;
123         uint8_t *buf;
124         uint8_t *srcp = (uint8_t *)val;
125                 
126         if((bytes <= 0) || (rep < 1)) return 0;
127         if(val == NULL) return 0;
128         buf = (uint8_t *)malloc(bytes); // swap buffer
129         if(buf == NULL) return 0;
130         for(members = 0; members < rep; members++) {
131                 if(fio->Fread(buf, bytes, 1) != 1) {
132                         free(buf);
133                         return members;
134                 }
135                 *sum = calc_crc32(*sum, buf, bytes);
136 #if defined(__LITTLE_ENDIAN__)
137                 int k = 0;
138                 for(int j = (bytes - 1); j >= 0; j--) {
139                         srcp[k] = buf[j];
140                         k++;
141                 }
142 #else // BIG_ENDIAN
143                 memcpy(srcp, buf, bytes);
144 #endif
145                 srcp += bytes;
146         }
147         free(buf);
148         return members;
149 }
150
151 void csp_state_data_saver::put_byte(uint8_t val, uint32_t *sumseed, bool *__stat)
152 {
153         
154         if(fio != NULL) {
155                 if(fio->IsOpened()) {
156                         fio->FputUint8(val);
157                         if(sumseed != NULL) {
158                                 *sumseed = calc_crc32(*sumseed, &val, 1);
159                         }
160                         if(__stat != NULL) *__stat =  true;
161                         return;
162                 }
163         }
164         if(__stat != NULL) *__stat =  false;
165         return;
166 }
167
168 uint8_t csp_state_data_saver::get_byte(uint32_t *sumseed, bool *__stat)
169 {
170         if(fio != NULL) {
171                 if(fio->IsOpened()) {
172                         uint8_t val = fio->FgetUint8();
173                         if(sumseed != NULL) {
174                                 *sumseed = calc_crc32(*sumseed, &val, 1);
175                         }
176                         if(__stat != NULL) *__stat =  true;
177                         return val;
178                 }
179         }
180         if(__stat != NULL) *__stat =  false;
181         return 0x00000000;
182 }
183
184 void csp_state_data_saver::put_bool(bool val, uint32_t *sumseed, bool *__stat)
185 {
186         uint8_t tv;
187         tv = (val == false) ? 0x00 : 0x01;
188         if(fio != NULL) {
189                 if(fio->IsOpened()) {
190                         fio->FputUint8(tv);
191                         if(sumseed != NULL) {
192                                 *sumseed = calc_crc32(*sumseed, &tv, 1);
193                         }
194                         if(__stat != NULL) *__stat =  true;
195                         return;
196                 }
197         }
198         if(__stat != NULL) *__stat =  false;
199         return;
200 }
201
202 bool csp_state_data_saver::get_bool(uint32_t *sumseed, bool *__stat)
203 {
204         if(fio != NULL) {
205                 if(fio->IsOpened()) {
206                         uint8_t val = fio->FgetUint8();
207                         if(val != 0x00) val = 0x01;
208                         if(sumseed != NULL) {
209                                 *sumseed = calc_crc32(*sumseed, &val, 1);
210                         }
211                         if(__stat != NULL) *__stat =  true;
212                         return (val == 0x00) ? false : true;
213                 }
214         }
215         if(__stat != NULL) *__stat =  false;
216         return false;
217 }
218
219 void csp_state_data_saver::put_word(uint16_t val, uint32_t *sumseed, bool *__stat)
220 {
221         if(fio != NULL) {
222                 if(fio->IsOpened()) {
223                         fio->FputUint16_BE(val);
224                         if(sumseed != NULL) {
225                                 pair_t tval;
226                                 uint8_t buf[2];
227                                 tval.w.l = val;
228                                 tval.write_2bytes_be_to(buf);
229                                 *sumseed = calc_crc32(*sumseed, buf, 2);
230                         }
231                         if(__stat != NULL) *__stat =  true;
232                         return;
233                 }
234         }
235         if(__stat != NULL) *__stat =  false;
236         return;
237 }
238
239 uint16_t csp_state_data_saver::get_word(uint32_t *sumseed, bool *__stat)
240 {
241         if(fio != NULL) {
242                 if(fio->IsOpened()) {
243                         uint16_t val = fio->FgetUint16_BE();
244                         if(__stat != NULL) *__stat =  true;
245                         if(sumseed != NULL) {
246                                 pair_t tval;
247                                 uint8_t buf[2];
248                                 tval.w.l = val;
249                                 tval.write_2bytes_be_to(buf);
250                                 *sumseed = calc_crc32(*sumseed, buf, 2);
251                         }
252                         return val;
253                 }
254         }
255         if(__stat != NULL) *__stat =  false;
256         return 0x00000000;
257 }
258
259 void csp_state_data_saver::put_dword(uint32_t val, uint32_t *sumseed, bool *__stat)
260 {
261         
262         if(fio != NULL) {
263                 if(fio->IsOpened()) {
264                         fio->FputUint32_BE(val);
265                         if(__stat != NULL) *__stat =  true;
266                         if(sumseed != NULL) {
267                                 pair_t tval;
268                                 uint8_t buf[4];
269                                 tval.d = val;
270                                 tval.write_4bytes_be_to(buf);
271                                 *sumseed = calc_crc32(*sumseed, buf, 4);
272                         }
273                         return;
274                 }
275         }
276         if(__stat != NULL) *__stat =  false;
277         return;
278 }
279
280 uint32_t csp_state_data_saver::get_dword(uint32_t *sumseed, bool *__stat)
281 {
282         if(fio != NULL) {
283                 if(fio->IsOpened()) {
284                         uint32_t val = fio->FgetUint32_BE();
285                         if(__stat != NULL) *__stat =  true;
286                         if(sumseed != NULL) {
287                                 pair_t tval;
288                                 uint8_t buf[4];
289                                 tval.d = val;
290                                 tval.write_4bytes_be_to(buf);
291                                 *sumseed = calc_crc32(*sumseed, buf, 4);
292                         }
293                         return val;
294                 }
295         }
296         if(__stat != NULL) *__stat =  false;
297         return 0x00000000;
298 }
299
300 void csp_state_data_saver::put_qword(uint64_t val, uint32_t *sumseed, bool *__stat)
301 {
302         
303         if(fio != NULL) {
304                 if(fio->IsOpened()) {
305                         fio->FputUint64_BE(val);
306                         if(__stat != NULL) *__stat =  true;
307                         if(sumseed != NULL) {
308                                 pair64_sav_t tval;
309                                 uint8_t buf[8];
310                                 tval.u64 = val;
311                                 tval.write_8bytes_be_to(buf);
312                                 *sumseed = calc_crc32(*sumseed, buf, 8);
313                         }
314                         return;
315                 }
316         }
317         if(__stat != NULL) *__stat =  false;
318         return;
319 }
320
321 uint64_t csp_state_data_saver::get_qword(uint32_t *sumseed, bool *__stat)
322 {
323         if(fio != NULL) {
324                 if(fio->IsOpened()) {
325                         uint64_t val = fio->FgetUint64_BE();
326                         if(__stat != NULL) *__stat =  true;
327                         if(sumseed != NULL) {
328                                 pair64_sav_t tval;
329                                 uint8_t buf[8];
330                                 tval.u64 = val;
331                                 tval.write_8bytes_be_to(buf);
332                                 *sumseed = calc_crc32(*sumseed, buf, 8);
333                         }
334                         return val;
335                 }
336         }
337         if(__stat != NULL) *__stat =  false;
338         return 0x00000000;
339 }
340
341 void csp_state_data_saver::put_int8(int8_t val, uint32_t *sumseed, bool *__stat)
342 {
343         
344         if(fio != NULL) {
345                 if(fio->IsOpened()) {
346                         fio->FputInt8(val);
347                         if(__stat != NULL) *__stat =  true;
348                         if(sumseed != NULL) {
349                                 *sumseed = calc_crc32(*sumseed, &val, 1);
350                         }
351                         return;
352                 }
353         }
354         if(__stat != NULL) *__stat = false;
355         return;
356 }
357
358 int8_t csp_state_data_saver::get_int8(uint32_t *sumseed, bool *__stat)
359 {
360         if(fio != NULL) {
361                 if(fio->IsOpened()) {
362                         int8_t val = fio->FgetInt8();
363                         if(__stat != NULL) *__stat = true;
364                         if(sumseed != NULL) {
365                                 *sumseed = calc_crc32(*sumseed, &val, 1);
366                         }
367                         return val;
368                 }
369         }
370         if(__stat != NULL) *__stat = false;
371         return 0x00000000;
372 }
373
374 void csp_state_data_saver::put_int16(int16_t val, uint32_t *sumseed, bool *__stat)
375 {
376         
377         if(fio != NULL) {
378                 if(fio->IsOpened()) {
379                         fio->FputInt16_BE(val);
380                         if(__stat != NULL) *__stat = true;
381                         if(sumseed != NULL) {
382                                 pair_t tval;
383                                 uint8_t buf[2];
384                                 tval.sw.l = val;
385                                 tval.write_2bytes_be_to(buf);
386                                 *sumseed = calc_crc32(*sumseed, buf, 2);
387                         }
388                         return;
389                 }
390         }
391         if(__stat != NULL) *__stat = false;
392         return;
393 }
394
395 int16_t csp_state_data_saver::get_int16(uint32_t *sumseed, bool *__stat)
396 {
397         if(fio != NULL) {
398                 if(fio->IsOpened()) {
399                         int16_t val = fio->FgetInt16_BE();
400                         if(__stat != NULL) *__stat = true;
401                         if(sumseed != NULL) {
402                                 pair_t tval;
403                                 uint8_t buf[2];
404                                 tval.sw.l = val;
405                                 tval.write_2bytes_be_to(buf);
406                                 *sumseed = calc_crc32(*sumseed, buf, 2);
407                         }
408                         return val;
409                 }
410         }
411         if(__stat != NULL) *__stat = false;
412         return 0x00000000;
413 }
414
415 void csp_state_data_saver::put_int32(int32_t val, uint32_t *sumseed, bool *__stat)
416 {
417         
418         if(fio != NULL) {
419                 if(fio->IsOpened()) {
420                         fio->FputInt32_BE(val);
421                         if(__stat != NULL) *__stat = true;
422                         if(sumseed != NULL) {
423                                 pair_t tval;
424                                 uint8_t buf[4];
425                                 tval.sd = val;
426                                 tval.write_4bytes_be_to(buf);
427                                 *sumseed = calc_crc32(*sumseed, buf, 4);
428                         }
429                         return;
430                 }
431         }
432         if(__stat != NULL) *__stat = false;
433         return;
434 }
435
436 int32_t csp_state_data_saver::get_int32(uint32_t *sumseed, bool *__stat)
437 {
438         if(fio != NULL) {
439                 if(fio->IsOpened()) {
440                         int32_t val = fio->FgetInt32_BE();
441                         if(__stat != NULL) *__stat = true;
442                         if(sumseed != NULL) {
443                                 pair_t tval;
444                                 uint8_t buf[4];
445                                 tval.sd = val;
446                                 tval.write_4bytes_be_to(buf);
447                                 *sumseed = calc_crc32(*sumseed, buf, 4);
448                         }
449                         return val;
450                 }
451         }
452         if(__stat != NULL) *__stat = false;
453         return 0x00000000;
454 }
455
456 void csp_state_data_saver::put_int64(int64_t val, uint32_t *sumseed, bool *__stat)
457 {
458         
459         if(fio != NULL) {
460                 if(fio->IsOpened()) {
461                         fio->FputInt64_BE(val);
462                         if(__stat != NULL) *__stat = true;
463                         if(sumseed != NULL) {
464                                 pair64_sav_t tval;
465                                 uint8_t buf[8];
466                                 tval.s64 = val;
467                                 tval.write_8bytes_be_to(buf);
468                                 *sumseed = calc_crc32(*sumseed, buf, 8);
469                         }
470                         return;
471                 }
472         }
473         if(__stat != NULL) *__stat = false;
474         return;
475 }
476
477 int64_t csp_state_data_saver::get_int64(uint32_t *sumseed, bool *__stat)
478 {
479         if(fio != NULL) {
480                 if(fio->IsOpened()) {
481                         int64_t val = fio->FgetInt64_BE();
482                         if(__stat != NULL) *__stat = true;
483                         if(sumseed != NULL) {
484                                 pair64_sav_t tval;
485                                 uint8_t buf[8];
486                                 tval.s64 = val;
487                                 tval.write_8bytes_be_to(buf);
488                                 *sumseed = calc_crc32(*sumseed, buf, 8);
489                         }
490                         return val;
491                 }
492         }
493         if(__stat != NULL) *__stat = false;
494         return 0x00000000;
495 }
496
497 /*
498  * For floating values, internal format is differnt by ARCHTECTURE, OS, COMPILER etc.
499  * So, saving / loading those values by ascii, not binary.
500  * -- 20180520 K.Ohta.
501  */
502 #include <stdexcept>
503
504 float csp_state_data_saver::get_float(uint32_t *sumseed, bool *__stat)
505 {
506         size_t _sp;
507         std::string _s;
508         char tmps[1024]; // OK?
509         float _v;
510         size_t _nlen = sizeof(tmps) / sizeof(char);
511         size_t donelen;
512         if(fio != NULL) {
513                 memset(tmps, 0x00, sizeof(tmps));
514                 donelen = load_string_data(tmps, sumseed, _nlen - 1); 
515                 if((donelen <= 0) || (donelen >= _nlen)) {  // 
516                         if(__stat != NULL) *__stat = false;
517                         return 0.0f;
518                 }
519                 _s = std::string(tmps);
520                 try {
521                         _v = std::stof(_s, &_sp);
522                 } catch(const std::invalid_argument& e) {
523                         if(__stat != NULL) *__stat = false;
524                         return 0.0f;
525                 } catch(const std::out_of_range& e) {
526                         if(__stat != NULL) *__stat =  false;
527                         return 0.0f;
528                 }
529                 if(__stat != NULL) *__stat =  true;
530                 if(sumseed != NULL) {
531                         *sumseed = calc_crc32(*sumseed, tmps, donelen);
532                 }
533                 return _v;
534         }
535         if(__stat != NULL) *__stat =  true;
536         return 0.0f;
537 }
538
539 void csp_state_data_saver::put_float(float val, uint32_t *sumseed, bool *__stat)
540 {
541         std::string _s;
542         char tmps[1024]; // OK?
543         float _v = val;
544         int _nlen = sizeof(tmps) / sizeof(char);
545         size_t donelen;
546         if(fio != NULL) {
547                 memset(tmps, 0x00, sizeof(tmps));
548                 _s = std::to_string(_v);
549                 _s.copy(tmps, _nlen - 1);
550                 size_t rlen = strnlen(tmps, _nlen);
551                 if((rlen <= 0) || (rlen >= _nlen)) { //
552                         if(__stat != NULL) *__stat =  false;
553                         return;
554                 }
555                 donelen = save_string_data(tmps, sumseed, rlen);
556                 if((donelen <= 0) || (donelen != (rlen + 1))) {
557                         if(__stat != NULL) *__stat =  false;
558                         return;
559                 }                       
560                 if(sumseed != NULL) {
561                         *sumseed = calc_crc32(*sumseed, tmps, donelen);
562                 }
563                 if(__stat != NULL) *__stat =  true;
564                 return;
565         }
566         if(__stat != NULL) *__stat =  false;
567         return;
568 }
569
570 double csp_state_data_saver::get_double(uint32_t *sumseed, bool *__stat)
571 {
572         std::string _s;
573         char tmps[1024]; // OK?
574         double _v;
575         size_t _nlen = sizeof(tmps) / sizeof(char);
576         size_t donelen;
577         size_t _sp;
578         if(fio != NULL) {
579                 memset(tmps, 0x00, sizeof(tmps));
580                 donelen = load_string_data(tmps, sumseed, _nlen - 1); 
581                 if((donelen <= 0) || (donelen >= _nlen)) {  // 
582                         if(__stat != NULL) *__stat =  false;
583                         return 0.0;
584                 }
585                 _s = std::string(tmps);
586                 try {
587                         _v = std::stod(_s, &_sp);
588                 } catch(const std::invalid_argument& e) {
589                         if(__stat != NULL) *__stat =  false;
590                         return 0.0;
591                 } catch(const std::out_of_range& e) {
592                         if(__stat != NULL) *__stat =  false;
593                         return 0.0;
594                 }
595                 if(__stat != NULL) *__stat =  true;
596                 if(sumseed != NULL) {
597                         *sumseed = calc_crc32(*sumseed, tmps, donelen);
598                 }
599                 return _v;
600         }
601         if(__stat != NULL) *__stat =  true;
602         return 0.0;
603 }
604
605 void csp_state_data_saver::put_double(double val, uint32_t *sumseed, bool *__stat)
606 {
607         std::string _s;
608         char tmps[1024]; // OK?
609         double _v = val;
610         int _nlen = sizeof(tmps) / sizeof(char);
611         size_t donelen;
612         if(fio != NULL) {
613                 memset(tmps, 0x00, sizeof(tmps));
614                 _s = std::to_string(_v);
615                 _s.copy(tmps, _nlen - 1);
616                 size_t rlen = strnlen(tmps, _nlen);
617                 if((rlen <= 0) || (rlen >= _nlen)) { //
618                         if(__stat != NULL) *__stat =  false;
619                         return;
620                 }
621                 donelen = save_string_data(tmps, sumseed, rlen);
622                 if((donelen <= 0) || (donelen != (rlen + 1))) {
623                         if(__stat != NULL) *__stat =  false;
624                         return;
625                 }                       
626                 if(sumseed != NULL) {
627                         *sumseed = calc_crc32(*sumseed, tmps, donelen);
628                 }
629                 if(__stat != NULL) *__stat =  true;
630                 return;
631         }
632         if(__stat != NULL) *__stat =  false;
633         return;
634 }
635
636 long double csp_state_data_saver::get_long_double(uint32_t *sumseed, bool *__stat)
637 {
638         size_t _sp;
639         std::string _s;
640         char tmps[1024]; // OK?
641         long double _v;
642         size_t _nlen = sizeof(tmps) / sizeof(char);
643         size_t donelen;
644         if(fio != NULL) {
645                 memset(tmps, 0x00, sizeof(tmps));
646                 donelen = load_string_data(tmps, sumseed, _nlen - 1); 
647                 if((donelen <= 0) || (donelen >= _nlen)) {  // 
648                         if(__stat != NULL) *__stat =  false;
649                         return 0.0;
650                 }
651                 _s = std::string(tmps);
652                 try {
653                         _v = std::stold(_s, &_sp);
654                 } catch(const std::invalid_argument& e) {
655                         if(__stat != NULL) *__stat =  false;
656                         return 0.0;
657                 } catch(const std::out_of_range& e) {
658                         if(__stat != NULL) *__stat =  false;
659                         return 0.0;
660                 }
661                 if(__stat != NULL) *__stat =  true;
662                 if(sumseed != NULL) {
663                         *sumseed = calc_crc32(*sumseed, tmps, donelen);
664                 }
665                 return _v;
666         }
667         if(__stat != NULL) *__stat =  true;
668         return 0.0;
669 }
670
671 void csp_state_data_saver::put_long_double(long double val, uint32_t *sumseed, bool *__stat)
672 {
673         std::string _s;
674         char tmps[1024]; // OK?
675         long double _v = val;
676         int _nlen = sizeof(tmps) / sizeof(char);
677         size_t donelen;
678         if(fio != NULL) {
679                 memset(tmps, 0x00, sizeof(tmps));
680                 _s = std::to_string(_v);
681                 _s.copy(tmps, _nlen - 1);
682                 size_t rlen = strnlen(tmps, _nlen);
683                 if((rlen <= 0) || (rlen >= _nlen)) { //
684                         if(__stat != NULL) *__stat =  false;
685                         return;
686                 }
687                 donelen = save_string_data(tmps, sumseed, rlen);
688                 if((donelen <= 0) || (donelen != (rlen + 1))) {
689                         if(__stat != NULL) *__stat =  false;
690                         return;
691                 }                       
692                 if(sumseed != NULL) {
693                         *sumseed = calc_crc32(*sumseed, tmps, donelen);
694                 }
695                 if(__stat != NULL) *__stat =  true;
696                 return;
697         }
698         if(__stat != NULL) *__stat =  false;
699         return;
700 }
701
702 size_t csp_state_data_saver::get_byte_array(uint8_t *p, size_t len, size_t repeat, uint32_t *sumseed, bool *__stat)
703 {
704         size_t donelen = 0;
705         bool _nstat = true;
706         if((len <= 0) || (repeat <= 0) || (p == NULL)) {
707                 _nstat = false;
708         }
709         if(fio == NULL) _nstat = false;
710         if(_nstat) {
711                 donelen = fio->Fread(p, len, repeat);
712                 if(donelen != repeat) {
713                         _nstat = false;
714                 } else {
715                         // Data OK.
716                         int calcsize = len * donelen;
717                         if((calcsize > 0) && (sumseed != NULL)) {
718                                 *sumseed = calc_crc32(*sumseed, p, calcsize);
719                         }
720                         _nstat = true;
721                 }
722         }
723         if(__stat != NULL) *__stat =  _nstat;
724         if(_nstat) {
725                 return len * donelen; // RETURN BYTES;
726         } else {
727                 return -1;
728         }
729 }
730
731 size_t csp_state_data_saver::put_byte_array(uint8_t *p, size_t len, size_t repeat, uint32_t *sumseed, bool *__stat)
732 {
733         size_t donelen = 0;
734         bool _nstat = true;
735         if((len <= 0) || (repeat <= 0) || (p == NULL)) {
736                 _nstat = false;
737         }
738         if(fio == NULL) _nstat = false;
739         if(_nstat) {
740                 donelen = fio->Fwrite(p, len, repeat);
741                 if(donelen != repeat) {
742                         _nstat = false;
743                 } else {
744                         // Data OK.
745                         int calcsize = len * donelen;
746                         if((calcsize > 0) && (sumseed != NULL)) {
747                                 *sumseed = calc_crc32(*sumseed, p, calcsize);
748                         }
749                         _nstat = true;
750                 }
751         }
752         if(__stat != NULL) *__stat =  _nstat;
753         if(_nstat) {
754                 return len * donelen; // RETURN BYTES;
755         } else {
756                 return -1;
757         }
758 }
759
760
761 void csp_state_data_saver::put_pair32(pair_t val, uint32_t *sumseed, bool *__stat)
762 {
763         
764         if(fio != NULL) {
765                 if(fio->IsOpened()) {
766                         uint8_t buf[4];
767                         val.write_4bytes_be_to(buf);
768                         size_t memb = fio->Fwrite(buf, 1, 4);
769                         if(memb != 4) {
770                                 if(__stat != NULL) *__stat =  false;
771                                 return;
772                         }
773                         if(__stat != NULL) *__stat = true;
774                         if(sumseed != NULL) {
775                                 *sumseed = calc_crc32(*sumseed, buf, 4);
776                         }
777                         return;
778                 }
779         }
780         if(__stat != NULL) *__stat = false;
781         return;
782 }
783
784 pair_t csp_state_data_saver::get_pair32(uint32_t *sumseed, bool *__stat)
785 {
786         pair_t val;
787         val.d = 0;
788         if(fio != NULL) {
789                 if(fio->IsOpened()) {
790                         uint8_t buf[4];
791                         size_t memb = fio->Fread(buf, 1, 4);
792                         if(memb != 4) {
793                                 if(__stat != NULL) *__stat = false;
794                                 return val;
795                         }
796                         val.read_4bytes_be_from(buf);
797                         if(__stat != NULL) *__stat = true;
798                         if(sumseed != NULL) {
799                                 *sumseed = calc_crc32(*sumseed, buf, 4);
800                         }
801                         return val;
802                 }
803         }
804         if(__stat != NULL) *__stat = false;
805         return val;
806 }
807
808 pair64_sav_t csp_state_data_saver::get_pair64(uint32_t *sumseed, bool *__stat)
809 {
810         pair64_sav_t val;
811         val.u64 = 0;
812         if(fio != NULL) {
813                 if(fio->IsOpened()) {
814                         uint8_t buf[8];
815                         size_t memb = fio->Fread(buf, 1, 8);
816                         if(memb != 8) {
817                                 if(__stat != NULL) *__stat = false;
818                                 return val;
819                         }
820                         val.read_8bytes_be_from(buf);
821                         if(__stat != NULL) *__stat = true;
822                         if(sumseed != NULL) {
823                                 *sumseed = calc_crc32(*sumseed, buf, 8);
824                         }
825                         return val;
826                 }
827         }
828         if(__stat != NULL) *__stat = false;
829         return val;
830 }
831
832 void csp_state_data_saver::put_pair64(pair64_sav_t val, uint32_t *sumseed, bool *__stat)
833 {
834         if(fio != NULL) {
835                 if(fio->IsOpened()) {
836                         uint8_t buf[8];
837                         val.write_8bytes_be_to(buf);
838                         size_t memb = fio->Fwrite(buf, 1, 8);
839                         if(memb != 8) {
840                                 if(__stat != NULL) *__stat = false;
841                                 return;
842                         }
843                         if(__stat != NULL) *__stat = true;
844                         if(sumseed != NULL) {
845                                 *sumseed = calc_crc32(*sumseed, buf, 8);
846                         }
847                         return;
848                 }
849         }
850         if(__stat != NULL) *__stat = false;
851         return;
852 }
853
854 csp_state_utils::csp_state_utils(int _version, int device_id, const _TCHAR *classname, CSP_Logger* p_logger)
855 {
856         listptr.clear();
857         crc_value = 0;
858         listptr.clear();
859                 
860         this_device_id = device_id;
861         this_device_id_bak = this_device_id;
862         logger = p_logger;
863         
864         memset(__classname, 0x00, sizeof(__classname));
865         memset(__classname_bak, 0x00, sizeof(__classname_bak));
866         memset(magic, 0x00, sizeof(magic));
867         memset(magic_bak, 0x00, sizeof(magic_bak));
868         
869         strncpy(magic, _T("CSP_SAVE"), 16 - 1);
870         strncpy(magic_bak, magic, 16 - 1);
871         
872         if(classname != NULL) {
873                 strncpy(__classname, classname, sizeof(__classname) - 1); 
874         } else {
875                 strncpy(__classname, "Unknown Class", sizeof(__classname) - 1); 
876         }
877         strncpy(__classname_bak, __classname, sizeof(__classname_bak) - 1);
878                 
879         class_version = _version;
880         class_version_bak = _version;
881
882         internal_version = 1;
883         internal_version_bak = internal_version;
884         out_debug_log("NEW SAVE STATE: NAME=%s DEVID=%d VER=%d", classname, device_id, _version);
885         
886         add_entry_tchar(_T("HEADER"), magic_bak, strlen(magic_bak) + 1);
887         add_entry_tchar(_T("CLASSNAME"), __classname_bak, strlen(__classname_bak) + 1);
888         add_entry(_T("DEVICE_ID"), &this_device_id_bak);
889         add_entry(_T("STAVE_VER"), &class_version_bak); 
890         add_entry(_T("INTERNAL_VER"), &internal_version_bak);   
891
892         fio = NULL;
893 }
894
895 csp_state_utils::~csp_state_utils()
896 {
897 }
898
899 /*
900  * Note: 
901  * With MinGW and DLL linker, not able top find extern symbols.
902  */
903
904 #include "config.h"
905 #include "csp_logger.h"
906
907 void csp_state_utils::out_debug_log(const char *fmt, ...)
908 {
909         if(logger == NULL) return;
910         // Temporally disabled 20180618
911 //#if !defined(__MINGW32__) && !defined(__MINGW64__)
912         char strbuf[8192];
913         va_list ap;
914         va_start(ap, fmt);      
915         vsnprintf(strbuf, 8192, fmt, ap);
916         logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_VM_STATE, strbuf);
917         va_end(ap);
918 //#endif
919 }
920
921 std::list<std::string> csp_state_utils::get_entries_list(void)
922 {
923         __list_t _l;
924         std::list<std::string> _rlist;
925         std::string _tname, _vname;
926         _rlist.clear();
927                 
928         for(auto p = listptr.begin(); p != listptr.end(); ++p) {
929                 void *pp = (*p).ptr;
930                 if(pp != NULL) {
931                         _vname = _T("NAME:");
932                         switch((*p).type_id) {
933                         case csp_saver_entry_float:
934                                 _tname = _T("TYPE: float");
935                                 break;
936                         case csp_saver_entry_double:
937                                 _tname = _T("TYPE: double");
938                                 break;
939                         case csp_saver_entry_long_double:
940                                 _tname = _T("TYPE: long double");
941                                 break;
942                         case csp_saver_entry_pair:
943                                 _tname = _T("TYPE: pair_t");
944                                 break;
945                         case csp_saver_entry_int:
946                                 _tname = _T("TYPE: int");
947                                 break;
948                         case csp_saver_entry_uint8:
949                                 _tname = _T("TYPE: uint8_t");
950                                 break;
951                         case csp_saver_entry_int8:
952                                 _tname = _T("TYPE: int8_t");
953                                 break;
954                         case csp_saver_entry_uint16:
955                                 _tname = _T("TYPE: uint16_t");
956                                 break;
957                         case csp_saver_entry_int16:
958                                 _tname = _T("TYPE: int16_t");
959                                 break;
960                         case csp_saver_entry_uint32:
961                                 _tname = _T("TYPE: uint32_t");
962                                 break;
963                         case csp_saver_entry_int32:
964                                 _tname = _T("TYPE: int32_t");
965                                 break;
966                         case csp_saver_entry_uint64:
967                                 _tname = _T("TYPE: uint64_t");
968                                 break;
969                         case csp_saver_entry_int64:
970                                 _tname = _T("TYPE: int64_t");
971                                 break;
972                         case csp_saver_entry_bool:
973                                 _tname = _T("TYPE: bool");
974                                 break;
975                         case csp_saver_entry_tchar:
976                                 _tname = _T("TYPE: _TCHAR");
977                                 break;
978                         case csp_saver_entry_any:
979                                 _tname = _T("TYPE: ANY");
980                                 break;
981                         default:
982                                 _tname = _T("TYPE: ANY(UNKNOWN)");
983                                 break;
984                         }
985                         _vname = _vname + (*p).name;
986                         _rlist.push_back(_vname);
987                         _rlist.push_back(_tname);
988                 }
989         }
990         return _rlist;
991 }
992 uint32_t csp_state_utils::get_crc_value(void)
993 {
994         return crc_value;
995 }
996 void csp_state_utils::get_class_name(_TCHAR *buf, int len)
997 {
998         strncpy(buf, __classname_bak, ((size_t)len >= sizeof(__classname_bak)) ? (sizeof(__classname_bak) - 1) : len);
999 }
1000
1001
1002 void csp_state_utils::add_entry_fifo(const _TCHAR *__name, FIFO **p, int _len, int __num)
1003 {
1004         __list_t _l;
1005         std::string _name = std::string(__name);
1006         if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
1007         _l.ptr = (void *)p;
1008         _l.type_id = csp_saver_entry_any;
1009         _l.len = _len;
1010         _l.atomlen = 1;
1011         _l.name = _name;
1012         _l.datalenptr = NULL;
1013         _l.local_num = __num;
1014         _l.assume_byte = false;
1015         _l.type_id = csp_saver_entry_fifo;
1016         out_debug_log("ADD ENTRY: NAME=%s TYPE=FIFO len=%d atomlen=%d", _name.c_str(), _len, _l.atomlen);
1017         listptr.push_back(_l);
1018 }
1019
1020 void csp_state_utils::add_entry_cur_time_t(const _TCHAR *__name, cur_time_t *p, int _len, int __num)
1021 {
1022         __list_t _l;
1023         std::string _name = std::string(__name);
1024         if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
1025         _l.ptr = (void *)p;
1026         _l.type_id = csp_saver_entry_any;
1027         _l.len = _len;
1028         _l.atomlen = 1;
1029         _l.name = _name;
1030         _l.datalenptr = NULL;
1031         _l.local_num = __num;
1032         _l.assume_byte = false;
1033         _l.type_id = csp_saver_entry_cur_time_t;
1034         out_debug_log("ADD ENTRY: NAME=%s TYPE=CUR_TIME_T len=%d atomlen=%d", _name.c_str(), _len, _l.atomlen);
1035         listptr.push_back(_l);
1036 }
1037         
1038 void csp_state_utils::add_entry_tchar(const _TCHAR *__name, _TCHAR *p, int _len, int __num, bool is_const)
1039 {
1040         __list_t _l;
1041         std::string _name = std::string(__name);
1042         if(__num >= 0) _name = _name + std::string("_#[") +std::to_string(__num) + std::string("]");
1043                 
1044         if(p == NULL) return;
1045         _l.ptr = (void *)p;
1046         _l.type_id = csp_saver_entry_tchar;
1047         _l.len = _len;
1048         _l.atomlen = sizeof(_TCHAR);
1049         _l.name = _name;
1050         _l.local_num = __num;
1051         _l.assume_byte = true;
1052
1053         if(is_const) _l.type_id = _l.type_id | csp_saver_entry_const;
1054
1055         out_debug_log("ADD ENTRY: NAME=%s TYPE=_TCHAR* VAL=%s len=%d atomlen=%d HEAD=%08x", __name, p, _len, _l.atomlen, p);
1056         listptr.push_back(_l);
1057 }
1058
1059 bool csp_state_utils::save_state(FILEIO *__fio, uint32_t *pcrc)
1060 {
1061         const uint8_t initdata[4] = {0xff, 0xff, 0xff, 0xff};
1062         const uint8_t taildata[4] = {0x00, 0x00, 0x00, 0x00};
1063         int retval;
1064
1065         class_version_bak = class_version;
1066         this_device_id_bak = this_device_id;
1067         memset(__classname_bak, 0x00, sizeof(__classname_bak));
1068         strncpy(__classname_bak, __classname, sizeof(__classname) - 1);
1069         // Initialize crc;
1070         if(pcrc == NULL) {
1071                 crc_value = 0xffffffff;
1072         } else {
1073                 crc_value = *pcrc;
1074         }
1075         // Write header
1076         crc_value = calc_crc32(crc_value, initdata, 4);
1077
1078         out_debug_log("SAVE STATE: NAME=%s DEVID=%d VER=%d", __classname, this_device_id, class_version);
1079         
1080         fio = new csp_state_data_saver(__fio);
1081         if(fio != NULL) {
1082                 bool need_mfree = false;
1083                 for(auto p = listptr.begin(); p != listptr.end(); ++p) {
1084                         void *pp = NULL;
1085                         void *_ppshadow = NULL;
1086                         int _tid = (*p).type_id;
1087                         int _asize = (*p).atomlen;
1088                         int _len = (*p).len;
1089                         bool _stat;
1090
1091                         if((_tid & csp_saver_entry_const) != 0) {
1092                                 _ppshadow = (*p).ptr;
1093                                 if((*p).assume_byte) {
1094                                         pp = malloc(_len);
1095                                         memcpy(pp, _ppshadow, _len);
1096                                 } else {
1097                                         pp = malloc(_len * _asize);
1098                                         memcpy(pp, _ppshadow, _len * _asize);
1099                                 }
1100                                 _tid = _tid & 0xffff;
1101                                 need_mfree = true;
1102                                 if(((*p).assume_byte)) {
1103                                         if(_asize > 1) {
1104                                                 _len = _len / _asize;
1105                                         }
1106                                 }
1107                         } else if((_tid & csp_saver_entry_vararray) != 0) {
1108                                 if((*p).datalenptr != NULL) {
1109                                         _len = *((*p).datalenptr);
1110                                 } else {
1111                                         _len = 0;
1112                                 }
1113                                 (*p).len =_len;
1114                                 _tid = _tid & ((int)~csp_saver_entry_vararray);
1115                                 void **xp = (void **)((*p).ptr);
1116                                 if(*xp != NULL) {
1117                                         pp = (void *)(*xp);
1118                                 } else {
1119                                         pp = NULL;
1120                                         _len = 0;
1121                                 }
1122                                 fio->put_int32(_len, &crc_value, &_stat);
1123                                 out_debug_log("SAVE VARARRAY p=%08x len=%d atom=%d CRC=%08x",pp, _len, _asize, crc_value); 
1124                                 if(((*p).assume_byte) && (_asize > 1)) {
1125                                         _len = _len / _asize;
1126                                 }
1127                         } else {
1128                                 pp = (*p).ptr;
1129                         }
1130                         if((pp != NULL) && (_len > 0)) {
1131                                 switch(_tid) {
1132                                 case csp_saver_entry_float:
1133                                         {
1134                                                 retval = 0;
1135                                                 float *px = (float *)pp;
1136                                                 for(int i = 0; i < _len; i++) {
1137                                                         fio->put_float(px[i], &crc_value, &_stat);
1138                                                         if(!_stat) {
1139                                                                 retval = -1;
1140                                                                 break;
1141                                                         }
1142                                                         retval++;
1143                                                 }
1144                                         }
1145                                         break;
1146                                 case csp_saver_entry_double:
1147                                         {
1148                                                 retval = 0;
1149                                                 double *px = (double *)pp;
1150                                                 for(int i = 0; i < _len; i++) {
1151                                                         fio->put_double(px[i], &crc_value, &_stat);
1152                                                         if(!_stat) {
1153                                                                 retval = -1;
1154                                                                 break;
1155                                                         }
1156                                                         retval++;
1157                                                 }
1158                                         }
1159                                         break;
1160                                 case csp_saver_entry_long_double:
1161                                         {
1162                                                 retval = 0;
1163                                                 long double *px = (long double *)pp;
1164                                                 for(int i = 0; i < _len; i++) {
1165                                                         fio->put_long_double(px[i], &crc_value, &_stat);
1166                                                         if(!_stat) {
1167                                                                 retval = -1;
1168                                                                 break;
1169                                                         }
1170                                                         retval++;
1171                                                 }
1172                                         }
1173                                         break;
1174                                 case csp_saver_entry_pair:
1175                                         {
1176                                                 retval = 0;
1177                                                 pair_t *px = (pair_t *)pp;
1178                                                 for(int i = 0; i < _len; i++) {
1179                                                         fio->put_pair32(px[i], &crc_value, &_stat);
1180                                                         if(!_stat) {
1181                                                                 retval = -1;
1182                                                                 break;
1183                                                         }
1184                                                         retval++;
1185                                                 }
1186                                         }
1187                                         break;
1188                                 case csp_saver_entry_int:
1189                                         {
1190                                                 retval = 0;
1191                                                 int *px = (int *)pp;
1192                                                 for(int i = 0; i < _len; i++) {
1193                                                         fio->put_int32(px[i], &crc_value, &_stat);
1194                                                         if(!_stat) {
1195                                                                 retval = -1;
1196                                                                 break;
1197                                                         }
1198                                                         retval++;
1199                                                 }
1200                                         }
1201                                         break;
1202                                 case csp_saver_entry_uint8:
1203                                         {
1204                                                 retval = 0;
1205                                                 uint8_t *px = (uint8_t *)pp;
1206                                                 if(_len > 1) {
1207                                                         size_t _n = __fio->Fwrite(px, _len, 1);
1208                                                         if(_n != 1) {
1209                                                                 retval = 0;
1210                                                                 _stat = false;
1211                                                         } else {
1212                                                                 retval = _len;
1213                                                                 _stat = true;
1214                                                                 crc_value = calc_crc32(crc_value, px, _len);
1215                                                         }
1216                                                 } else {
1217                                                         fio->put_byte(*px, &crc_value, &_stat);
1218                                                         if(!_stat) {
1219                                                                 retval = -1;
1220                                                                 break;
1221                                                         }
1222                                                         retval++;
1223                                                 }
1224                                         }
1225                                         break;
1226                                 case csp_saver_entry_int8:
1227                                         {
1228                                                 retval = 0;
1229                                                 int8_t *px = (int8_t *)pp;
1230                                                 if(_len > 1) {
1231                                                         size_t _n = __fio->Fwrite(px, _len, 1);
1232                                                         if(_n != 1) {
1233                                                                 retval = 0;
1234                                                                 _stat = false;
1235                                                         } else {
1236                                                                 retval = _len;
1237                                                                 _stat = true;
1238                                                                 crc_value = calc_crc32(crc_value, (uint8_t *)px, _len);
1239                                                         }
1240                                                 } else {
1241                                                         fio->put_int8(*px, &crc_value, &_stat);
1242                                                         if(!_stat) {
1243                                                                 retval = -1;
1244                                                                 break;
1245                                                         }
1246                                                         retval++;
1247                                                 }
1248                                         }
1249                                         break;
1250                                 case csp_saver_entry_uint16:
1251                                         {
1252                                                 retval = 0;
1253                                                 uint16_t *px = (uint16_t *)pp;
1254                                                 for(int i = 0; i < _len; i++) {
1255                                                         fio->put_word(px[i], &crc_value, &_stat);
1256                                                         if(!_stat) {
1257                                                                 retval = -1;
1258                                                                 break;
1259                                                         }
1260                                                         retval++;
1261                                                 }
1262                                         }
1263                                         break;
1264                                 case csp_saver_entry_int16:
1265                                         {
1266                                                 retval = 0;
1267                                                 int16_t *px = (int16_t *)pp;
1268                                                 for(int i = 0; i < _len; i++) {
1269                                                         fio->put_int16(px[i], &crc_value, &_stat);
1270                                                         if(!_stat) {
1271                                                                 retval = -1;
1272                                                                 break;
1273                                                         }
1274                                                         retval++;
1275                                                 }
1276                                         }
1277                                         break;
1278                                 case csp_saver_entry_uint32:
1279                                         {
1280                                                 retval = 0;
1281                                                 uint32_t *px = (uint32_t *)pp;
1282                                                 for(int i = 0; i < _len; i++) {
1283                                                         fio->put_dword(px[i], &crc_value, &_stat);
1284                                                         if(!_stat) {
1285                                                                 retval = -1;
1286                                                                 break;
1287                                                         }
1288                                                         retval++;
1289                                                 }
1290                                         }
1291                                         break;
1292                                 case csp_saver_entry_int32:
1293                                         {
1294                                                 retval = 0;
1295                                                 int32_t *px = (int32_t *)pp;
1296                                                 for(int i = 0; i < _len; i++) {
1297                                                         fio->put_int32(px[i], &crc_value, &_stat);
1298                                                         if(!_stat) {
1299                                                                 retval = -1;
1300                                                                 break;
1301                                                         }
1302                                                         retval++;
1303                                                 }
1304                                         }
1305                                         break;
1306                                 case csp_saver_entry_uint64:
1307                                         {
1308                                                 retval = 0;
1309                                                 uint64_t *px = (uint64_t *)pp;
1310                                                 for(int i = 0; i < _len; i++) {
1311                                                         fio->put_qword(px[i], &crc_value, &_stat);
1312                                                         if(!_stat) {
1313                                                                 retval = -1;
1314                                                                 break;
1315                                                         }
1316                                                         retval++;
1317                                                 }
1318                                         }
1319                                         break;
1320                                 case csp_saver_entry_int64:
1321                                         {
1322                                                 retval = 0;
1323                                                 int64_t *px = (int64_t *)pp;
1324                                                 for(int i = 0; i < _len; i++) {
1325                                                         fio->put_int64(px[i], &crc_value, &_stat);
1326                                                         if(!_stat) {
1327                                                                 retval = -1;
1328                                                                 break;
1329                                                         }
1330                                                         retval++;
1331                                                 }
1332                                         }
1333                                         break;
1334                                 case csp_saver_entry_bool:
1335                                         {
1336                                                 retval = 0;
1337                                                 bool *px = (bool *)pp;
1338                                                 for(int i = 0; i < _len ; i++) {
1339                                                         fio->put_bool(px[i], &crc_value, &_stat);
1340                                                         if(!_stat) {
1341                                                                 retval = -1;
1342                                                                 break;
1343                                                         }
1344                                                         retval++;
1345                                                 }
1346                                         }
1347                                         break;
1348                                 case csp_saver_entry_tchar:
1349                                         {
1350                                                 retval = fio->save_string_data((const _TCHAR *)pp, &crc_value, _len, &_stat);
1351                                                 if(!_stat) retval = -1;
1352                                         }
1353                                         break;
1354                                 case csp_saver_entry_any:
1355                                         {
1356                                                 retval = fio->put_byte_array((uint8_t *)pp, _asize, _len, &crc_value, &_stat);
1357                                                 if(!_stat) retval = -1;
1358                                         }
1359                                         break;
1360                                 case csp_saver_entry_fifo:
1361                                         if(pp != NULL) {
1362                                                 FIFO **fp = (FIFO **)pp;
1363                                                 for(int i = 0; i < _len; i++) {
1364                                                         fp[i]->save_state_helper(fio, &crc_value, &_stat);
1365                                                 }
1366                                                 retval = _len;
1367                                         }
1368                                         break;
1369                                 case csp_saver_entry_cur_time_t:
1370                                         if(pp != NULL) {
1371                                                 cur_time_t *fp = (cur_time_t *)pp;
1372                                                 for(int i = 0; i < _len; i++) {
1373                                                         fp[i].save_state_helper(fio, &crc_value, &_stat);
1374                                                 }
1375                                                 retval = _len;
1376                                         }
1377                                         break;
1378                                 default:
1379                                         retval = 0;
1380                                         break;
1381                                 }
1382                                 if((retval <= 0) || (!_stat)) {
1383                                         if(need_mfree) {
1384                                                 if(pp != NULL) free(pp);
1385                                         }
1386                                         delete fio;
1387                                         return false;
1388                                 }
1389
1390                         }
1391                         //out_debug_log("CRC=%08x", crc_value);
1392                         if(need_mfree) {
1393                                 if(pp != NULL) free(pp);
1394                         }
1395                         need_mfree = false;
1396                 }
1397                 delete fio;
1398         }
1399         fio = NULL;
1400         // embed CRC
1401         crc_value = calc_crc32(crc_value, taildata, 4);
1402         __fio->FputUint32_BE(crc_value);
1403         out_debug_log("CRC: VAL=%08x", crc_value);
1404         if(pcrc != NULL) *pcrc = crc_value;
1405         return true;
1406 }
1407
1408 bool csp_state_utils::load_state(FILEIO *__fio, uint32_t *pcrc)
1409 {
1410         const uint8_t initdata[4] = {0xff, 0xff, 0xff, 0xff};
1411         const uint8_t taildata[4] = {0x00, 0x00, 0x00, 0x00};
1412         int retval;
1413         // Initialize crc;
1414         //class_version_bak = class_version;
1415         //this_device_id_bak = this_device_id;
1416         memset(__classname_bak, 0x00, sizeof(__classname_bak));
1417         //strncpy(__classname_bak, __classname, sizeof(__classname));
1418         if(pcrc == NULL) {
1419                 crc_value = 0xffffffff;
1420         } else {
1421                 crc_value = *pcrc;
1422         }
1423         crc_value = calc_crc32(crc_value, initdata, 4);
1424
1425         fio = new csp_state_data_saver(__fio);
1426         out_debug_log("LOAD STATE: NAME=%s DEVID=%d VER=%d", __classname, this_device_id, class_version);
1427         if(fio != NULL) {
1428                 bool need_mfree = false;
1429                 for(auto p = listptr.begin(); p != listptr.end(); ++p) {
1430                         void *pp = NULL;
1431                         int _tid = (*p).type_id;
1432                         int _asize = (*p).atomlen;
1433                         int _len = (*p).len;
1434                         std::string _name = (*p).name;
1435                         bool _stat;
1436                         
1437                         if((_tid & csp_saver_entry_const) != 0) {
1438                                 //_ppshadow = (*p).ptr;
1439                                 if((*p).assume_byte) {
1440                                         pp = malloc(_len);
1441                                         //memcpy(pp, _ppshadow, _len);
1442                                 } else {
1443                                         pp = malloc(_len * _asize);
1444                                         //memcpy(pp, _ppshadow, _len * asize);
1445                                 }
1446                                 _tid = _tid & 0xffff;
1447                                 need_mfree = true;
1448                                 if(((*p).assume_byte)) {
1449                                         if(_asize > 1) {
1450                                                 _len = _len / _asize;
1451                                         }
1452                                 }
1453                         } else  if((_tid & csp_saver_entry_vararray) != 0) {
1454                                 _len = fio->get_int32(&crc_value, &_stat);
1455                                 void **xp = (void **)((*p).ptr);
1456                                 if(*xp != NULL) {
1457                                         free(*xp);
1458                                 }
1459                                 *xp = NULL;
1460                                 if(_len > 0) {
1461                                         if(((*p).assume_byte)) {
1462                                                 *xp = malloc(_len);
1463                                         } else {
1464                                                 *xp = malloc(_asize * _len);
1465                                         }
1466                                         if(*xp == NULL) _len = 0;
1467                                 }
1468                                 if((*p).datalenptr != NULL) {
1469                                         *((*p).datalenptr) = _len;
1470                                 }
1471                                 pp = *xp;
1472                                 _tid = _tid & ((int)~csp_saver_entry_vararray);
1473                                 if(((*p).assume_byte)) {
1474                                         if(_asize > 1) {
1475                                                 _len = _len / _asize;
1476                                         }
1477                                 }
1478                                 out_debug_log("LOAD VARARRAY p=%08x len=%d atom=%d CRC=%08x",pp, _len, _asize, crc_value); 
1479                         } else {
1480                                 pp = (*p).ptr;
1481                         }
1482                         if((pp != NULL) && (_len > 0)) {
1483                                 switch(_tid) {
1484                                 case csp_saver_entry_float:
1485                                         {
1486                                                 retval = 0;
1487                                                 float *px = (float *)pp;
1488                                                 for(int i = 0; i < _len; i++) {
1489                                                         px[i] = fio->get_float(&crc_value, &_stat);
1490                                                         if(!_stat) {
1491                                                                 retval = -1;
1492                                                                 break;
1493                                                         }
1494                                                         retval++;
1495                                                 }
1496                                         }
1497                                         out_debug_log("NAME=%s FLOAT: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1498                                         break;
1499                                 case csp_saver_entry_double:
1500                                         {
1501                                                 retval = 0;
1502                                                 double *px = (double *)pp;
1503                                                 for(int i = 0; i < _len; i++) {
1504                                                         px[i] = fio->get_double(&crc_value, &_stat);
1505                                                         if(!_stat) {
1506                                                                 retval = -1;
1507                                                                 break;
1508                                                         }
1509                                                         retval++;
1510                                                 }
1511                                         }
1512                                         out_debug_log("NAME=%s DOUBLE: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1513                                         break;
1514                                 case csp_saver_entry_long_double:
1515                                         {
1516                                                 retval = 0;
1517                                                 long double *px = (long double *)pp;
1518                                                 for(int i = 0; i < _len; i++) {
1519                                                         px[i] = fio->get_long_double(&crc_value, &_stat);
1520                                                         if(!_stat) {
1521                                                                 retval = -1;
1522                                                                 break;
1523                                                         }
1524                                                         retval++;
1525                                                 }
1526                                         }
1527                                         out_debug_log("NAME=%s LONG DOUBLE: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1528                                         break;
1529                                 case csp_saver_entry_pair:
1530                                         {
1531                                                 retval = 0;
1532                                                 pair_t *px = (pair_t *)pp;
1533                                                 for(int i = 0; i < _len; i++) {
1534                                                         px[i] = fio->get_pair32(&crc_value, &_stat);
1535                                                         if(!_stat) {
1536                                                                 retval = -1;
1537                                                                 break;
1538                                                         }
1539                                                         retval++;
1540                                                 }
1541                                         }
1542                                         out_debug_log("NAME=%s PAIR_T: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0,pp);
1543                                         break;
1544                                 case csp_saver_entry_int:
1545                                         {
1546                                                 retval = 0;
1547                                                 int *px = (int *)pp;
1548                                                 for(int i = 0; i < _len; i++) {
1549                                                         px[i] = fio->get_int32(&crc_value, &_stat);
1550                                                         if(!_stat) {
1551                                                                 retval = -1;
1552                                                                 break;
1553                                                         }
1554                                                         retval++;
1555                                                 }
1556                                         }
1557                                         out_debug_log("NAME=%s INT: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1558                                         break;
1559                                 case csp_saver_entry_uint8:
1560                                         {
1561                                                 retval = 0;
1562                                                 uint8_t *px = (uint8_t *)pp;
1563                                                 if((_len > 1) && (px != NULL)) {
1564                                                         size_t _n = __fio->Fread(px, _len, 1);
1565                                                         if(_n != 1) {
1566                                                                 retval = 0;
1567                                                                 _stat = false;
1568                                                         } else {
1569                                                                 retval = _len;
1570                                                                 _stat = true;
1571                                                                 crc_value = calc_crc32(crc_value, px, _len);
1572                                                         }
1573                                                 } else {
1574                                                         *px = fio->get_byte(&crc_value, &_stat);
1575                                                         if(!_stat) {
1576                                                                 retval = -1;
1577                                                                 break;
1578                                                         }
1579                                                         retval++;
1580                                                 }
1581                                         }
1582                                         out_debug_log("NAME=%s UINT8: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1583                                         break;
1584                                 case csp_saver_entry_int8:
1585                                         {
1586                                                 retval = 0;
1587                                                 int8_t *px = (int8_t *)pp;
1588                                                 if((_len > 1) && (px != NULL)) {
1589                                                         size_t _n = __fio->Fread(px, _len, 1);
1590                                                         if(_n != 1) {
1591                                                                 retval = 0;
1592                                                                 _stat = false;
1593                                                         } else {
1594                                                                 retval = _len;
1595                                                                 _stat = true;
1596                                                                 crc_value = calc_crc32(crc_value, px, _len);
1597                                                         }
1598                                                 } else {
1599                                                         *px = fio->get_int8(&crc_value, &_stat);
1600                                                         if(!_stat) {
1601                                                                 retval = -1;
1602                                                                 break;
1603                                                         }
1604                                                         retval++;
1605                                                 }
1606                                         }
1607                                         out_debug_log("NAME=%s INT8: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1608                                         break;
1609                                 case csp_saver_entry_uint16:
1610                                         {
1611                                                 retval = 0;
1612                                                 uint16_t *px = (uint16_t *)pp;
1613                                                 for(int i = 0; i < _len; i++) {
1614                                                         px[i] = fio->get_word(&crc_value, &_stat);
1615                                                         if(!_stat) {
1616                                                                 retval = -1;
1617                                                                 break;
1618                                                         }
1619                                                         retval++;
1620                                                 }
1621                                         }
1622                                         out_debug_log("NAMEE=%s UINT16: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1623                                         break;
1624                                 case csp_saver_entry_int16:
1625                                         {
1626                                                 retval = 0;
1627                                                 int16_t *px = (int16_t *)pp;
1628                                                 for(int i = 0; i < _len; i++) {
1629                                                         px[i] = fio->get_int16(&crc_value, &_stat);
1630                                                         if(!_stat) {
1631                                                                 retval = -1;
1632                                                                 break;
1633                                                         }
1634                                                         retval++;
1635                                                 }
1636                                         }
1637                                         out_debug_log("NAME=%s INT16: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1638                                         break;
1639                                 case csp_saver_entry_uint32:
1640                                         {
1641                                                 retval = 0;
1642                                                 uint32_t *px = (uint32_t *)pp;
1643                                                 for(int i = 0; i < _len; i++) {
1644                                                         px[i] = fio->get_dword(&crc_value, &_stat);
1645                                                         if(!_stat) {
1646                                                                 retval = -1;
1647                                                                 break;
1648                                                         }
1649                                                 retval++;
1650                                                 }
1651                                         }
1652                                         out_debug_log("NAME=%s UINT32: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1653                                         break;
1654                                 case csp_saver_entry_int32:
1655                                         {
1656                                                 retval = 0;
1657                                                 int32_t *px = (int32_t *)pp;
1658                                                 for(int i = 0; i < _len; i++) {
1659                                                         px[i] = fio->get_int32(&crc_value, &_stat);
1660                                                         if(!_stat) {
1661                                                                 retval = -1;
1662                                                                 break;
1663                                                         }
1664                                                         retval++;
1665                                                 }
1666                                         }
1667                                         out_debug_log("NAME=%s INT32: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1668                                         break;
1669                                 case csp_saver_entry_uint64:
1670                                         {
1671                                                 retval = 0;
1672                                                 uint64_t *px = (uint64_t *)pp;
1673                                                 for(int i = 0; i < _len; i++) {
1674                                                         px[i] = fio->get_qword(&crc_value, &_stat);
1675                                                         if(!_stat) {
1676                                                                 retval = -1;
1677                                                                 break;
1678                                                         }
1679                                                         retval++;
1680                                                 }
1681                                                 
1682                                         }
1683                                         out_debug_log("NAME=%s UINT64: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1684                                         break;
1685                                 case csp_saver_entry_int64:
1686                                         {
1687                                                 retval = 0;
1688                                                 int64_t *px = (int64_t *)pp;
1689                                                 for(int i = 0; i < _len; i++) {
1690                                                         px[i] = fio->get_int64(&crc_value, &_stat);
1691                                                         if(!_stat) {
1692                                                                 retval = -1;
1693                                                                 break;
1694                                                         }
1695                                                 retval++;
1696                                                 }
1697                                         }
1698                                         out_debug_log("NAME=%s INT64: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1699                                         break;
1700                                 case csp_saver_entry_bool:
1701                                         {
1702                                                 retval = 0;
1703                                                 bool *px = (bool *)pp;
1704                                                 for(int i = 0; i < _len; i++) {
1705                                                         px[i] = fio->get_bool(&crc_value, &_stat);
1706                                                         if(!_stat) {
1707                                                                 retval = -1;
1708                                                                 break;
1709                                                         }
1710                                                 retval++;
1711                                                 }
1712                                         }
1713                                         out_debug_log("NAME=%s BOOL: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1714                                         break;
1715                                 case csp_saver_entry_tchar:
1716                                         {
1717                                                 retval = fio->load_string_data((const _TCHAR *)pp, &crc_value, _len, &_stat);
1718                                                 out_debug_log("NAME=%s STR: LEN=%d STAT=%d S=%s", _name.c_str(), retval, (_stat) ? 1 : 0, (_TCHAR *)pp);
1719                                                 if(!_stat) retval = -1;
1720                                         }
1721                                         break;
1722                                 case csp_saver_entry_any:
1723                                         {
1724                                                 retval = fio->get_byte_array((uint8_t *)pp, _asize, _len, &crc_value, &_stat);
1725                                                 if(!_stat) retval = -1;
1726                                                 out_debug_log("NAME=%s BYTE-ARRAY: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), retval, (_stat) ? 1 : 0, pp);
1727                                         }
1728                                         break;
1729                                 case csp_saver_entry_fifo:
1730                                         if(pp != NULL) {
1731                                                 FIFO **fp = (FIFO **)pp;
1732                                                 bool _s = false;
1733                                                 for(int i = 0; i < _len; i++) {
1734                                                         _s = fp[i]->load_state_helper(fio, &crc_value, &_stat);
1735                                                         if(!(_s)) {
1736                                                                 retval = -1;
1737                                                                 _stat = false;
1738                                                                 break;
1739                                                         }
1740                                                 }
1741                                                 if(_s) retval = _len;
1742                                         }
1743                                         break;
1744                                 case csp_saver_entry_cur_time_t:
1745                                         if(pp != NULL) {
1746                                                 cur_time_t *fp = (cur_time_t *)pp;
1747                                                 bool _s = false;
1748                                                 for(int i = 0; i < _len; i++) {
1749                                                         _s = fp[i].load_state_helper(fio, &crc_value, &_stat);
1750                                                         if(!(_s)) {
1751                                                                 retval = -1;
1752                                                                 _stat = false;
1753                                                                 break;
1754                                                         }
1755                                                 }
1756                                                 if(_s) retval = _len;
1757                                         }
1758                                         break;
1759                                 default:
1760                                         retval = 0;
1761                                         out_debug_log("NAME=%s UNKNOWN TID=%d: LEN=%d STAT=%d HEAD=%08x", _name.c_str(), _tid, retval, (_stat) ? 1 : 0, pp);
1762                                         break;
1763                                 }
1764                                 if((retval <= 0) || (!_stat)) {
1765                                         if(need_mfree) {
1766                                                 if(pp != NULL) free(pp);
1767                                         }
1768                                         delete fio;
1769                                         return false;
1770                                 }
1771                         }
1772                         out_debug_log("CRC=%08x", crc_value);
1773                         if(need_mfree) {
1774                                 if(memcmp(pp, (*p).ptr , _len * _asize) != 0) {
1775                                         delete fio;
1776                                         free(pp);
1777                                         return false;
1778                                 }
1779                                 free(pp);
1780                         }
1781                         need_mfree = false;
1782                 }
1783                 delete fio;
1784         }
1785         fio = NULL;
1786         crc_value = calc_crc32(crc_value, taildata, 4);
1787         if(pcrc != NULL) *pcrc = crc_value;
1788         // check CRC
1789         uint32_t cmpval = __fio->FgetUint32_BE();
1790         if(cmpval != crc_value) {
1791                 out_debug_log("CRC_ERROR: VAL=%08x / %08x", cmpval, crc_value);
1792                 return false;
1793         }
1794         // Check header
1795         if(this_device_id != this_device_id_bak) {
1796                 out_debug_log("WRONG device_id %d", this_device_id_bak);
1797                 return false;
1798         }
1799         if(class_version != class_version_bak) {
1800                 out_debug_log("WRONG crass_version %d", class_version_bak);
1801                 return false;
1802         }
1803         if(strncmp(__classname, __classname_bak, sizeof(__classname)) != 0) {
1804                 out_debug_log("WRONG CRASS NAME %s", __classname_bak);
1805                 return false;
1806         }
1807         out_debug_log("OK CRC=%08x", crc_value);
1808         return true;
1809 }