8 __attribute__((unused)) static void UnusedFunction()
11 a.OnGetDataFromString(null);
12 a.OnGetString(null, 0, 0);
15 extern int __ecereVMethodID_class_OnGetDataFromString;
16 extern int __ecereVMethodID_class_OnGetString;
17 extern int __ecereVMethodID_class_OnFree;
20 public enum JSONResult { syntaxError, success, typeMismatch, noItem };
22 public enum SetBool : uint
26 /*public property bool // NOT WORKING!
28 set { return value ? true : false; }
29 get { return (this == true); }
34 public class JSONParser
42 while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '/'))
48 JSONResult GetValue(Class type, DataValue value)
50 JSONResult result = syntaxError;
56 result = GetString(&string);
60 if(type && (!strcmp(type.name, "String") || !strcmp(type.dataTypeString, "char *")))
64 else if(type && (type.type == enumClass || type.type == unitClass))
66 if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, &value.i, string))
69 result = typeMismatch;
72 else if(type && (prop = eClass_FindProperty(type, "String", type.module)))
74 // TOFIX: Add more conversion property support... Expecting void * compatible here
75 value.p = ((void *(*)())(void *)prop.Set)(string);
79 else if(type && (type.type == structClass))
81 if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, value.p, string))
84 result = typeMismatch;
90 result = typeMismatch;
97 if(type && eClass_IsDerived(type, class(Map)))
99 result = GetMap(type, (Map *)&array);
102 result = GetArray(type, &array);
104 if(result == success && type && eClass_IsDerived(type, class(Container)))
113 if(result != success)
114 result = typeMismatch;
117 else if(ch == '-' || isdigit(ch))
119 result = GetNumber(type, value);
123 void * object = value.p;
124 result = GetObject(type, &object);
127 if(type && type.type == structClass);
128 else if(type && (type.type == normalClass || type.type == noHeadClass || type.type == bitClass))
134 result = typeMismatch;
136 ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, object);
144 while(c < sizeof(buffer)-1 && isalpha(ch))
147 if(!f.Getc(&ch)) break;
154 if(!strcmp(type.name, "bool"))
156 if(!strcmpi(buffer, "false")) value.i = 0;
157 else if(!strcmpi(buffer, "true")) value.i = 1;
159 result = typeMismatch;
161 else if(!strcmp(type.name, "SetBool"))
163 if(!strcmpi(buffer, "false")) value.i = SetBool::false;
164 else if(!strcmpi(buffer, "true")) value.i = SetBool::true;
166 result = typeMismatch;
168 else if(!strcmpi(buffer, "null"))
170 if(type.type != structClass)
174 result = typeMismatch;
177 result = typeMismatch;
179 else if(ch == '}' || ch == ']')
184 JSONResult GetArray(Class type, Container * array)
186 JSONResult result = syntaxError;
191 *array = eInstance_New(type);
196 Class arrayType = null;
197 JSONResult itemResult;
199 if(eClass_IsDerived(type, class(Container)))
201 arrayType = type.templateArgs[0].dataTypeClass;
204 if(arrayType && arrayType.type == structClass)
205 value.p = new0 byte[arrayType.structSize];
206 itemResult = GetValue(arrayType, value);
207 if(itemResult == success)
209 // TODO: Verify the matching between template type and uint64
211 if(arrayType.type == structClass)
213 t = (uint64)(uintptr)value.p;
215 else if(arrayType == class(double) || !strcmp(arrayType.dataTypeString, "double"))
217 t = value.ui64; //*(uint64 *)&value.d;
219 else if(arrayType == class(float) || !strcmp(arrayType.dataTypeString, "float"))
221 t = value.ui; //f*(uint *)&value.f;
223 else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64") ||
224 !strcmp(arrayType.dataTypeString, "unsigned int64") || !strcmp(arrayType.dataTypeString, "uint64"))
228 else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
229 !strcmp(arrayType.dataTypeString, "unsigned int") || !strcmp(arrayType.dataTypeString, "uint"))
233 else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
234 !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
235 !strcmp(arrayType.dataTypeString, "int16"))
239 else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
240 !strcmp(arrayType.dataTypeString, "unsigned char") || !strcmp(arrayType.dataTypeString, "byte"))
246 t = (uint64)(uintptr)value.p;
248 ((void *(*)(void *, uint64))(void *)array->Add)(*array, t);
250 if(arrayType && arrayType.type == structClass)
255 if(itemResult == typeMismatch)
258 PrintLn("Warning: Incompatible value for array value, expected ", (String)arrayType.name);
260 else if(itemResult == noItem)
266 if(result != syntaxError)
268 if(ch != ']' && ch != ',')
278 result = syntaxError;
286 JSONResult GetMap(Class type, Map * map)
288 JSONResult result = syntaxError;
293 Class mapNodeType = type.templateArgs[0].dataTypeClass;
294 Class keyType = mapNodeType.templateArgs[0].dataTypeClass;
295 Property keyProp = null;
296 if(keyType && !strcmp(keyType.dataTypeString, "char *"))
297 keyProp = eClass_FindProperty(mapNodeType, "key", mapNodeType.module);
299 *map = eInstance_New(type);
306 JSONResult itemResult;
308 itemResult = GetValue(mapNodeType, value);
309 if(itemResult == success)
311 String s = keyProp ? ((void * (*)(void *))(void *)keyProp.Get)(value.p) : null;
312 ((void *(*)(void *, uint64))(void *)map->Add)(*map, (uint64)(uintptr)value.p);
313 // Must free String keys here
318 if(itemResult == typeMismatch)
321 PrintLn("Warning: Incompatible value for array value, expected ", (String)mapNodeType.name);
323 else if(itemResult == noItem)
329 if(result != syntaxError)
331 if(ch != ']' && ch != ',')
341 result = syntaxError;
349 JSONResult GetString(String * string)
351 JSONResult result = syntaxError;
352 Array<char> buffer { minAllocSize = 256 };
353 bool escaped = false;
361 if(ch == '\\' && !escaped)
367 if(ch == 'b') ch = '\b';
368 else if(ch == 'f') ch = '\f';
369 else if(ch == 'n') ch = '\n';
370 else if(ch == 'r') ch = '\r';
371 else if(ch == 't') ch = '\t';
388 if(buffer.minAllocSize < buffer.count)
389 buffer.minAllocSize *= 2;
393 *string = CopyString(buffer.array);
397 if(ch != ',' && ch != '}')
402 public JSONResult GetObject(Class objectType, void ** object)
404 JSONResult result = syntaxError;
405 if(!objectType || objectType.type != structClass)
410 Class mapKeyClass = null, mapDataClass = null;
412 if(objectType && objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
414 mapKeyClass = objectType.templateArgs[0].dataTypeClass;
415 mapDataClass = objectType.templateArgs[2].dataTypeClass;
419 if(objectType && (objectType.type == noHeadClass || objectType.type == normalClass))
421 *object = eInstance_New(objectType);
423 else if(objectType && objectType.type != structClass)
425 *object = eSystem_New(objectType.typeSize);
432 if(GetString(&string))
434 DataMember member = null;
435 Property prop = null;
442 string[0] = (char)tolower(string[0]);
443 if(mapKeyClass && !strcmp(string, "key"))
445 prop = eClass_FindProperty(objectType, "key", objectType.module);
449 else if(mapDataClass && !strcmp(string, "value"))
451 prop = eClass_FindProperty(objectType, "value", objectType.module);
456 member = eClass_FindDataMember(objectType, string, objectType.module, null, null);
459 type = eSystem_FindClass(__thisModule, member.dataTypeString);
461 type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
463 offset = member._class.offset + member.offset;
467 prop = eClass_FindProperty(objectType, string, objectType.module);
470 type = eSystem_FindClass(__thisModule, prop.dataTypeString);
472 type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
475 PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
479 // Find Member in Object Class
483 if(type && type.type == structClass)
487 value.p = (byte *)*object + offset;
488 memset(value.p, 0, type.structSize);
492 value.p = new0 byte[type.structSize];
499 JSONResult itemResult = GetValue(type, value);
500 if(itemResult != syntaxError)
506 PrintLn("warning: Unresolved data type ", member ? (String)member.dataTypeString : (String)prop.dataTypeString);
508 else if(itemResult == success)
513 // TOFIX: How to swiftly handle classes with base data type?
514 if(type.type == structClass)
516 else if(type.type == normalClass || type.type == noHeadClass)
518 void ** ptr = (void**)((byte *)*object + offset);
519 if(eClass_IsDerived(type, class(Container)) && *ptr)
521 Container container = (Container)*ptr;
527 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
529 *(double *)((byte *)*object + offset) = value.d;
531 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
533 *(float *)((byte *)*object + offset) = value.f;
535 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
536 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
538 *(uint64 *)((byte *)*object + offset) = value.ui64;
540 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
541 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
543 *(int *)((byte *)*object + offset) = value.i;
545 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
546 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
547 !strcmp(type.dataTypeString, "int16"))
549 *(short *)((byte *)*object + offset) = value.s;
551 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
552 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
554 *(char *)((byte *)*object + offset) = value.c;
558 *(void **)((byte *)*object + offset) = value.p;
561 else if(prop && prop.Set)
563 if(!strcmp(type.dataTypeString, "char *"))
565 ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
569 else if(type.type == enumClass || type.type == bitClass || type.type == unitClass || type.type == systemClass)
571 // TOFIX: How to swiftly handle classes with base data type?
572 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
574 ((void (*)(void *, double))(void *)prop.Set)(*object, value.d);
576 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
578 ((void (*)(void *, float))(void *)prop.Set)(*object, value.f);
580 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
581 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
583 ((void (*)(void *, uint64))(void *)prop.Set)(*object, value.ui64);
585 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
586 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
588 ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
590 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
591 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
592 !strcmp(type.dataTypeString, "int16"))
594 ((void (*)(void *, short))(void *)prop.Set)(*object, value.s);
596 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
597 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
599 ((void (*)(void *, char))(void *)prop.Set)(*object, value.c);
603 ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
608 ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
614 PrintLn("Warning: Incompatible value for ", member ? (String)member.name : (String)prop.name,
615 ", expected ", member ? (String)member.dataTypeString : (String)prop.dataTypeString);
621 result = syntaxError;
623 if(prop && type.type == structClass)
629 else if(ch && ch != '}' && ch != ',')
630 result = syntaxError;
641 result = syntaxError;
649 JSONResult GetNumber(Class type, DataValue value)
651 JSONResult result = syntaxError;
654 while(c < sizeof(buffer)-1 && (ch == '-' || ch == '.' || tolower(ch) == 'e' || ch == '+' || isdigit(ch)))
657 if(!f.Getc(&ch)) break;
660 //if(strchr(buffer, '.'))
661 if(!type) return success;
663 // TOFIX: How to swiftly handle classes with base data type?
664 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
666 value.d = strtod(buffer, null);
669 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
671 value.f = (float)strtod(buffer, null);
674 // TOFIX: int64 looks for class long long?
675 //else if(type == class(int64) || !strcmp(type.dataTypeString, "int64"))
676 else if(!strcmp(type.dataTypeString, "int64"))
678 value.i64 = strtol(buffer, null, 10); // TOFIX: 64 bit support
681 else if(type == class(uint64) || !strcmp(type.dataTypeString, "uint64"))
683 value.ui64 = strtoul(buffer, null, 10); // TOFIX: 64 bit support
686 else if(type == class(uint) || !strcmp(type.dataTypeString, "unsigned int"))
688 value.ui = (uint)strtoul(buffer, null, 10); // TOFIX: 64 bit support
693 value.i = (int)strtol(buffer, null, 10);
697 if(result == success && type.type == unitClass)
699 // Convert to reference unit
701 for(prop = type.conversions.first; prop; prop = prop.next)
703 bool refProp = false;
705 if(!strcmp(prop.name, type.base.fullName))
707 else if( (c = eSystem_FindClass(type.module, prop.name) ) )
710 for(p = c.conversions.first; p; p = p.next)
712 if(!strcmp(p.name, type.base.fullName) && !p.Set && !p.Get)
721 if(prop.Set && prop.Get)
723 const String dts = type.base.dataTypeString;
724 if(!strcmp(dts, "double"))
725 value.d = ((double(*)(double))(void *)prop.Get)(value.d);
726 else if(!strcmp(dts, "float"))
727 value.f = ((float(*)(float))(void *)prop.Get)(value.f);
728 else if(!strcmp(dts, "int"))
729 value.i = ((int(*)(int))(void *)prop.Get)(value.i);
730 else if(!strcmp(dts, "int64"))
731 value.i64 = ((int64(*)(int64))(void *)prop.Get)(value.i64);
732 else if(!strcmp(dts, "unsigned int"))
733 value.ui = ((uint(*)(uint))(void *)prop.Get)(value.ui);
734 else if(!strcmp(dts, "uint64"))
735 value.ui64 = ((uint64(*)(uint64))(void *)prop.Get)(value.ui64);
746 bool WriteMap(File f, Class type, Map map, int indent)
752 MapIterator it { map = map };
753 Class mapNodeClass = map._class.templateArgs[0].dataTypeClass;
759 MapNode n = (MapNode)it.pointer;
764 for(i = 0; i<indent; i++) f.Puts(" ");
765 _WriteJSONObject(f, mapNodeClass, n, indent);
769 for(i = 0; i<indent; i++) f.Puts(" ");
777 bool WriteArray(File f, Class type, Container array, int indent)
783 Iterator it { array };
784 Class arrayType = type.templateArgs[0].dataTypeClass;
791 uint64 t = ((uint64(*)(void *, void *))(void *)array.GetData)(array, it.pointer);
798 // TODO: Verify the matching between template type and uint64
799 if(arrayType.type == structClass)
801 value.p = (void *)(uintptr)t;
803 else if(arrayType == class(double) || !strcmp(arrayType.dataTypeString, "double"))
806 //value.d = *(double *)&t;
808 else if(arrayType == class(float) || !strcmp(arrayType.dataTypeString, "float"))
811 //value.f = *(float *)&t;
813 else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64") ||
814 !strcmp(arrayType.dataTypeString, "unsigned int64") || !strcmp(arrayType.dataTypeString, "uint64"))
818 else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
819 !strcmp(arrayType.dataTypeString, "unsigned int") || !strcmp(arrayType.dataTypeString, "uint"))
823 else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
824 !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
825 !strcmp(arrayType.dataTypeString, "int16"))
829 else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
830 !strcmp(arrayType.dataTypeString, "unsigned char") || !strcmp(arrayType.dataTypeString, "byte"))
836 value.p = (void *)(uintptr)t;
838 for(i = 0; i<indent; i++) f.Puts(" ");
839 WriteValue(f, arrayType, value, indent);
843 for(i = 0; i<indent; i++) f.Puts(" ");
851 bool WriteNumber(File f, Class type, DataValue value, int indent)
854 bool needClass = false;
857 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
858 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.d, buffer, 0, &needClass);
859 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
860 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.f, buffer, null, &needClass);
861 else if(!strcmp(type.dataTypeString, "int64"))
862 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.i64, buffer, null, &needClass);
863 else if(!strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64") || type.typeSize == sizeof(int64))
864 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui64, buffer, null, &needClass);
865 else if(!strcmp(type.dataTypeString, "int"))
866 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.i, buffer, null, &needClass);
867 else if(!strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint") || type.typeSize == sizeof(int))
868 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui, buffer, null, &needClass);
869 else if(!strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "int16"))
870 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.s, buffer, null, &needClass);
871 else if(!strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || type.typeSize == sizeof(short int))
872 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.us, buffer, null, &needClass);
873 else if(!strcmp(type.dataTypeString, "char"))
874 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.c, buffer, null, &needClass);
875 else if(!strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte") || type.typeSize == sizeof(byte))
876 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.uc, buffer, null, &needClass);
878 quote = (type.type == unitClass && ((buffer[0] != '.' && !isdigit(buffer[0])) || strchr(buffer, ' ')));
879 if(quote) f.Puts("\"");
881 if(quote) f.Puts("\"");
885 bool WriteValue(File f, Class type, DataValue value, int indent)
887 if(!strcmp(type.name, "String") || !strcmp(type.dataTypeString, "char *"))
894 //if(strchr(value.p, '\"') || strchr(value.p, '\\'))
899 char * string = value.p;
918 else if(b == sizeof(buffer)-2 || !ch)
921 if(ch) buffer[b] = 0;
935 else if(!strcmp(type.name, "bool"))
942 else if(!strcmp(type.name, "SetBool"))
944 if(value.i == SetBool::true)
946 else if(value.i == SetBool::false)
951 else if(type.type == enumClass)
954 WriteNumber(f, type, value, indent);
957 else if(eClass_IsDerived(type, class(Map)))
959 WriteMap(f, type, value.p, indent);
961 else if(eClass_IsDerived(type, class(Container)))
963 WriteArray(f, type, value.p, indent);
965 else if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
967 _WriteJSONObject(f, type, value.p, indent);
969 else if(type.type == bitClass)
972 dataType = eSystem_FindClass(__thisModule, type.dataTypeString);
973 WriteNumber(f, dataType, value, indent);
975 else if(type.type == systemClass || type.type == unitClass)
977 WriteNumber(f, type, value, indent);
982 public bool WriteJSONObject(File f, Class objectType, void * object, int indent)
987 result = _WriteJSONObject(f, objectType, object, indent);
993 static bool _WriteJSONObject(File f, Class objectType, void * object, int indent)
997 const char * string = null;
999 if(objectType._vTbl[__ecereVMethodID_class_OnGetString] != objectType.base._vTbl[__ecereVMethodID_class_OnGetString])
1003 string = ((const char *(*)())(void *)objectType._vTbl[__ecereVMethodID_class_OnGetString])(objectType, object, buffer, null, null);
1007 // TOCHECK: ProjectNode.ec why do we add quotes in OnGetString there?
1008 if(string[0] == '\"')
1021 bool isFirst = true;
1022 Class mapKeyClass = null, mapDataClass = null;
1024 List<Class> bases { };
1026 if(objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
1028 mapKeyClass = objectType.templateArgs[0].dataTypeClass;
1029 mapDataClass = objectType.templateArgs[2].dataTypeClass;
1035 for(baseClass = objectType; baseClass; baseClass = baseClass.base)
1037 if(baseClass.isInstanceClass || !baseClass.base)
1039 bases.Insert(null, baseClass);
1042 for(baseClass : bases)
1044 for(prop = baseClass.membersAndProperties.first; prop; prop = prop.next)
1046 if(prop.memberAccess != publicAccess || (prop.isProperty && (!prop.Set || !prop.Get))) continue;
1049 if(!prop.conversion && (!prop.IsSet || prop.IsSet(object)))
1051 DataValue value { };
1054 if(mapKeyClass && !strcmp(prop.name, "key"))
1056 else if(mapDataClass && !strcmp(prop.name, "value"))
1057 type = mapDataClass;
1059 type = eSystem_FindClass(__thisModule, prop.dataTypeString);
1061 type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
1063 PrintLn("warning: Unresolved data type ", (String)prop.dataTypeString);
1066 // TOFIX: How to swiftly handle classes with base data type?
1067 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
1069 value.d = ((double (*)(void *))(void *)prop.Get)(object);
1071 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
1073 value.f = ((float (*)(void *))(void *)prop.Get)(object);
1075 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
1076 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
1078 value.ui64 = ((uint64 (*)(void *))(void *)prop.Get)(object);
1080 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
1081 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
1083 value.i = ((int (*)(void *))(void *)prop.Get)(object);
1085 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
1086 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
1087 !strcmp(type.dataTypeString, "int16"))
1089 value.s = ((short (*)(void *))(void *)prop.Get)(object);
1091 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
1092 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
1094 value.c = ((char (*)(void *))(void *)prop.Get)(object);
1096 else if(type.type == structClass)
1098 value.p = new0 byte[type.structSize];
1099 ((void (*)(void *, void *))(void *)prop.Get)(object, value.p);
1103 value.p = ((void *(*)(void *))(void *)prop.Get)(object);
1106 if(!isFirst) f.Puts(",\n");
1107 for(c = 0; c<indent; c++) f.Puts(" ");
1110 f.Putc((char)toupper(prop.name[0]));
1111 f.Puts(prop.name+1);
1113 WriteValue(f, type, value, indent);
1115 if(type.type == structClass)
1122 DataMember member = (DataMember)prop;
1123 DataValue value { };
1125 Class type = eSystem_FindClass(__thisModule, member.dataTypeString);
1127 type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
1129 offset = member._class.offset + member.offset;
1133 if(type.type == normalClass || type.type == noHeadClass || type.type == structClass || !strcmp(type.name, "String"))
1135 if(type.type == structClass)
1136 value.p = (void *)((byte *)object + offset);
1138 value.p = *(void **)((byte *)object + offset);
1142 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
1144 value.d = *(double *)((byte *)object + offset);
1146 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
1148 value.f = *(float *)((byte *)object + offset);
1150 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
1151 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
1153 value.ui64 = *(uint64 *)((byte *)object + offset);
1155 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
1156 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
1158 value.i = *(int *)((byte *)object + offset);
1159 if(!strcmp(type.name, "bool") || type.type == enumClass)
1163 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
1164 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
1165 !strcmp(type.dataTypeString, "int16"))
1167 value.s = *(short *)((byte *)object + offset);
1169 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
1170 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
1172 value.c = *(char *)((byte *)object + offset);
1176 value.i = *(int *)((byte *)object + offset);
1179 if(!isFirst) f.Puts(",\n");
1180 for(c = 0; c<indent; c++) f.Puts(" ");
1183 f.Putc((char)toupper(member.name[0]));
1184 f.Puts(member.name+1);
1186 WriteValue(f, type, value, indent);
1197 for(c = 0; c<indent; c++) f.Puts(" "); f.Puts("}");