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 && eClass_IsDerived(type, class(ColorAlpha)))
81 result = GetColorAlpha(string, value);
83 else if(type && (type.type == structClass))
85 if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, value.p, string))
88 result = typeMismatch;
94 result = typeMismatch;
101 if(type && eClass_IsDerived(type, class(Map)))
103 result = GetMap(type, (Map *)&array);
106 result = GetArray(type, &array);
108 if(result == success && type && eClass_IsDerived(type, class(Container)))
117 if(result != success)
118 result = typeMismatch;
121 else if(ch == '-' || isdigit(ch))
123 result = GetNumber(type, value);
127 void * object = value.p;
128 result = GetObject(type, &object);
131 if(type && type.type == structClass);
132 else if(type && (type.type == normalClass || type.type == noHeadClass || type.type == bitClass))
138 result = typeMismatch;
140 ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, object);
148 while(c < sizeof(buffer)-1 && isalpha(ch))
151 if(!f.Getc(&ch)) break;
158 if(!strcmp(type.name, "bool"))
160 if(!strcmpi(buffer, "false")) value.i = 0;
161 else if(!strcmpi(buffer, "true")) value.i = 1;
163 result = typeMismatch;
165 else if(!strcmp(type.name, "SetBool"))
167 if(!strcmpi(buffer, "false")) value.i = SetBool::false;
168 else if(!strcmpi(buffer, "true")) value.i = SetBool::true;
170 result = typeMismatch;
172 else if(!strcmpi(buffer, "null"))
174 if(type.type != structClass)
178 result = typeMismatch;
181 result = typeMismatch;
183 else if(ch == '}' || ch == ']')
188 JSONResult GetArray(Class type, Container * array)
190 JSONResult result = syntaxError;
195 *array = eInstance_New(type);
200 Class arrayType = null;
201 JSONResult itemResult;
203 if(eClass_IsDerived(type, class(Container)))
205 arrayType = type.templateArgs[0].dataTypeClass;
208 if(arrayType && arrayType.type == structClass)
209 value.p = new0 byte[arrayType.structSize];
210 itemResult = GetValue(arrayType, value);
211 if(itemResult == success)
213 // TODO: Verify the matching between template type and uint64
215 if(arrayType.type == structClass)
217 t = (uint64)(uintptr)value.p;
219 else if(arrayType == class(double) || !strcmp(arrayType.dataTypeString, "double"))
221 t = value.ui64; //*(uint64 *)&value.d;
223 else if(arrayType == class(float) || !strcmp(arrayType.dataTypeString, "float"))
225 t = value.ui; //f*(uint *)&value.f;
227 else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64") ||
228 !strcmp(arrayType.dataTypeString, "unsigned int64") || !strcmp(arrayType.dataTypeString, "uint64"))
232 else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
233 !strcmp(arrayType.dataTypeString, "unsigned int") || !strcmp(arrayType.dataTypeString, "uint"))
237 else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
238 !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
239 !strcmp(arrayType.dataTypeString, "int16"))
243 else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
244 !strcmp(arrayType.dataTypeString, "unsigned char") || !strcmp(arrayType.dataTypeString, "byte"))
250 t = (uint64)(uintptr)value.p;
252 ((void *(*)(void *, uint64))(void *)array->Add)(*array, t);
254 if(arrayType && arrayType.type == structClass)
259 if(itemResult == typeMismatch)
262 PrintLn("Warning: Incompatible value for array value, expected ", (String)arrayType.name);
264 else if(itemResult == noItem)
270 if(result != syntaxError)
272 if(ch != ']' && ch != ',')
282 result = syntaxError;
290 JSONResult GetMap(Class type, Map * map)
292 JSONResult result = syntaxError;
297 Class mapNodeType = type.templateArgs[0].dataTypeClass;
298 Class keyType = mapNodeType.templateArgs[0].dataTypeClass;
299 Property keyProp = null;
300 if(keyType && !strcmp(keyType.dataTypeString, "char *"))
301 keyProp = eClass_FindProperty(mapNodeType, "key", mapNodeType.module);
303 *map = eInstance_New(type);
310 JSONResult itemResult;
312 itemResult = GetValue(mapNodeType, value);
313 if(itemResult == success)
315 String s = keyProp ? ((void * (*)(void *))(void *)keyProp.Get)(value.p) : null;
316 ((void *(*)(void *, uint64))(void *)map->Add)(*map, (uint64)(uintptr)value.p);
317 // Must free String keys here
322 if(itemResult == typeMismatch)
325 PrintLn("Warning: Incompatible value for array value, expected ", (String)mapNodeType.name);
327 else if(itemResult == noItem)
333 if(result != syntaxError)
335 if(ch != ']' && ch != ',')
345 result = syntaxError;
353 JSONResult GetString(String * string)
355 JSONResult result = syntaxError;
356 Array<char> buffer { minAllocSize = 256 };
357 bool escaped = false;
365 if(ch == '\\' && !escaped)
371 if(ch == 'b') ch = '\b';
372 else if(ch == 'f') ch = '\f';
373 else if(ch == 'n') ch = '\n';
374 else if(ch == 'r') ch = '\r';
375 else if(ch == 't') ch = '\t';
392 if(buffer.minAllocSize < buffer.count)
393 buffer.minAllocSize *= 2;
397 *string = CopyString(buffer.array);
401 if(ch != ',' && ch != '}')
406 public JSONResult GetObject(Class objectType, void ** object)
408 JSONResult result = syntaxError;
409 if(!objectType || objectType.type != structClass)
414 Class mapKeyClass = null, mapDataClass = null;
416 if(objectType && objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
418 mapKeyClass = objectType.templateArgs[0].dataTypeClass;
419 mapDataClass = objectType.templateArgs[2].dataTypeClass;
423 if(objectType && (objectType.type == noHeadClass || objectType.type == normalClass))
425 *object = eInstance_New(objectType);
427 else if(objectType && objectType.type != structClass)
429 *object = eSystem_New(objectType.typeSize);
436 if(GetString(&string))
438 DataMember member = null;
439 Property prop = null;
446 string[0] = (char)tolower(string[0]);
447 if(mapKeyClass && !strcmp(string, "key"))
449 prop = eClass_FindProperty(objectType, "key", objectType.module);
453 else if(mapDataClass && !strcmp(string, "value"))
455 prop = eClass_FindProperty(objectType, "value", objectType.module);
460 member = eClass_FindDataMember(objectType, string, objectType.module, null, null);
463 type = eSystem_FindClass(__thisModule, member.dataTypeString);
465 type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
467 offset = member._class.offset + member.offset;
471 prop = eClass_FindProperty(objectType, string, objectType.module);
474 type = eSystem_FindClass(__thisModule, prop.dataTypeString);
476 type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
479 PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
483 // Find Member in Object Class
487 if(type && type.type == structClass)
491 value.p = (byte *)*object + offset;
492 memset(value.p, 0, type.structSize);
496 value.p = new0 byte[type.structSize];
503 JSONResult itemResult = GetValue(type, value);
504 if(itemResult != syntaxError)
510 PrintLn("warning: Unresolved data type ", member ? (String)member.dataTypeString : (String)prop.dataTypeString);
512 else if(itemResult == success)
517 // TOFIX: How to swiftly handle classes with base data type?
518 if(type.type == structClass)
520 else if(type.type == normalClass || type.type == noHeadClass)
522 void ** ptr = (void**)((byte *)*object + offset);
523 if(eClass_IsDerived(type, class(Container)) && *ptr)
525 Container container = (Container)*ptr;
531 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
533 *(double *)((byte *)*object + offset) = value.d;
535 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
537 *(float *)((byte *)*object + offset) = value.f;
539 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
540 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
542 *(uint64 *)((byte *)*object + offset) = value.ui64;
544 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
545 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
547 *(int *)((byte *)*object + offset) = value.i;
549 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
550 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
551 !strcmp(type.dataTypeString, "int16"))
553 *(short *)((byte *)*object + offset) = value.s;
555 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
556 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
558 *(char *)((byte *)*object + offset) = value.c;
562 *(void **)((byte *)*object + offset) = value.p;
565 else if(prop && prop.Set)
567 if(!strcmp(type.dataTypeString, "char *"))
569 ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
573 else if(type.type == enumClass || type.type == bitClass || type.type == unitClass || type.type == systemClass)
575 // TOFIX: How to swiftly handle classes with base data type?
576 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
578 ((void (*)(void *, double))(void *)prop.Set)(*object, value.d);
580 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
582 ((void (*)(void *, float))(void *)prop.Set)(*object, value.f);
584 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
585 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
587 ((void (*)(void *, uint64))(void *)prop.Set)(*object, value.ui64);
589 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
590 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
592 ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
594 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
595 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
596 !strcmp(type.dataTypeString, "int16"))
598 ((void (*)(void *, short))(void *)prop.Set)(*object, value.s);
600 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
601 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
603 ((void (*)(void *, char))(void *)prop.Set)(*object, value.c);
607 ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
612 ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
618 PrintLn("Warning: Incompatible value for ", member ? (String)member.name : (String)prop.name,
619 ", expected ", member ? (String)member.dataTypeString : (String)prop.dataTypeString);
625 result = syntaxError;
627 if(prop && type.type == structClass)
633 else if(ch && ch != '}' && ch != ',')
634 result = syntaxError;
645 result = syntaxError;
653 JSONResult GetNumber(Class type, DataValue value)
655 JSONResult result = syntaxError;
658 while(c < sizeof(buffer)-1 && (ch == '-' || ch == '.' || tolower(ch) == 'e' || ch == '+' || isdigit(ch)))
661 if(!f.Getc(&ch)) break;
664 //if(strchr(buffer, '.'))
665 if(!type) return success;
667 // TOFIX: How to swiftly handle classes with base data type?
668 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
670 value.d = strtod(buffer, null);
673 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
675 value.f = (float)strtod(buffer, null);
678 // TOFIX: int64 looks for class long long?
679 //else if(type == class(int64) || !strcmp(type.dataTypeString, "int64"))
680 else if(!strcmp(type.dataTypeString, "int64"))
682 value.i64 = strtol(buffer, null, 10); // TOFIX: 64 bit support
685 else if(type == class(uint64) || !strcmp(type.dataTypeString, "uint64"))
687 value.ui64 = strtoul(buffer, null, 10); // TOFIX: 64 bit support
690 else if(type == class(uint) || !strcmp(type.dataTypeString, "unsigned int"))
692 value.ui = (uint)strtoul(buffer, null, 10); // TOFIX: 64 bit support
697 value.i = (int)strtol(buffer, null, 10);
701 if(result == success && type.type == unitClass)
703 // Convert to reference unit
705 for(prop = type.conversions.first; prop; prop = prop.next)
707 bool refProp = false;
709 if(!strcmp(prop.name, type.base.fullName))
711 else if( (c = eSystem_FindClass(type.module, prop.name) ) )
714 for(p = c.conversions.first; p; p = p.next)
716 if(!strcmp(p.name, type.base.fullName) && !p.Set && !p.Get)
725 if(prop.Set && prop.Get)
727 const String dts = type.base.dataTypeString;
728 if(!strcmp(dts, "double"))
729 value.d = ((double(*)(double))(void *)prop.Get)(value.d);
730 else if(!strcmp(dts, "float"))
731 value.f = ((float(*)(float))(void *)prop.Get)(value.f);
732 else if(!strcmp(dts, "int"))
733 value.i = ((int(*)(int))(void *)prop.Get)(value.i);
734 else if(!strcmp(dts, "int64"))
735 value.i64 = ((int64(*)(int64))(void *)prop.Get)(value.i64);
736 else if(!strcmp(dts, "unsigned int"))
737 value.ui = ((uint(*)(uint))(void *)prop.Get)(value.ui);
738 else if(!strcmp(dts, "uint64"))
739 value.ui64 = ((uint64(*)(uint64))(void *)prop.Get)(value.ui64);
749 JSONResult GetColorAlpha(String string, DataValue value)
751 ColorAlpha color = 0;
755 if(string[0] == '0' && string[1] == 'x')
756 color = (uint)strtoul(string, null, 0);
761 if((d = strchr(string, ',')))
763 a = (byte)atoi(string);
768 if(c.class::OnGetDataFromString(d))
774 color = (uint)strtoul(string, null, 16);
782 bool WriteMap(File f, Class type, Map map, int indent)
788 MapIterator it { map = map };
789 Class mapNodeClass = map._class.templateArgs[0].dataTypeClass;
795 MapNode n = (MapNode)it.pointer;
800 for(i = 0; i<indent; i++) f.Puts(" ");
801 _WriteJSONObject(f, mapNodeClass, n, indent);
805 for(i = 0; i<indent; i++) f.Puts(" ");
813 bool WriteArray(File f, Class type, Container array, int indent)
819 Iterator it { array };
820 Class arrayType = type.templateArgs[0].dataTypeClass;
827 uint64 t = ((uint64(*)(void *, void *))(void *)array.GetData)(array, it.pointer);
834 // TODO: Verify the matching between template type and uint64
835 if(arrayType.type == structClass)
837 value.p = (void *)(uintptr)t;
839 else if(arrayType == class(double) || !strcmp(arrayType.dataTypeString, "double"))
842 //value.d = *(double *)&t;
844 else if(arrayType == class(float) || !strcmp(arrayType.dataTypeString, "float"))
847 //value.f = *(float *)&t;
849 else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64") ||
850 !strcmp(arrayType.dataTypeString, "unsigned int64") || !strcmp(arrayType.dataTypeString, "uint64"))
854 else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
855 !strcmp(arrayType.dataTypeString, "unsigned int") || !strcmp(arrayType.dataTypeString, "uint"))
859 else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
860 !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
861 !strcmp(arrayType.dataTypeString, "int16"))
865 else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
866 !strcmp(arrayType.dataTypeString, "unsigned char") || !strcmp(arrayType.dataTypeString, "byte"))
872 value.p = (void *)(uintptr)t;
874 for(i = 0; i<indent; i++) f.Puts(" ");
875 WriteValue(f, arrayType, value, indent);
879 for(i = 0; i<indent; i++) f.Puts(" ");
887 bool WriteNumber(File f, Class type, DataValue value, int indent)
890 bool needClass = false;
893 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
894 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.d, buffer, 0, &needClass);
895 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
896 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.f, buffer, null, &needClass);
897 else if(!strcmp(type.dataTypeString, "int64"))
898 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.i64, buffer, null, &needClass);
899 else if(!strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64") || type.typeSize == sizeof(int64))
900 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui64, buffer, null, &needClass);
901 else if(!strcmp(type.dataTypeString, "int"))
902 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.i, buffer, null, &needClass);
903 else if(!strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint") || type.typeSize == sizeof(int))
904 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui, buffer, null, &needClass);
905 else if(!strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "int16"))
906 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.s, buffer, null, &needClass);
907 else if(!strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || type.typeSize == sizeof(short int))
908 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.us, buffer, null, &needClass);
909 else if(!strcmp(type.dataTypeString, "char"))
910 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.c, buffer, null, &needClass);
911 else if(!strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte") || type.typeSize == sizeof(byte))
912 ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.uc, buffer, null, &needClass);
914 quote = (type.type == unitClass && ((buffer[0] != '.' && !isdigit(buffer[0])) || strchr(buffer, ' ')));
915 if(quote) f.Puts("\"");
917 if(quote) f.Puts("\"");
921 public bool WriteColorAlpha(File f, Class type, DataValue value, int indent)
924 char * string = buffer;
925 ColorAlpha color = value.i;
928 DefinedColor c = color;
932 a.class::OnGetString(buffer, null, null);
933 len = strlen(buffer);
939 if(!c.class::OnGetString(string, null, null))
940 sprintf(buffer, "0x%x", color);
947 bool WriteValue(File f, Class type, DataValue value, int indent)
949 if(!strcmp(type.name, "String") || !strcmp(type.dataTypeString, "char *"))
956 //if(strchr(value.p, '\"') || strchr(value.p, '\\'))
961 char * string = value.p;
980 else if(b == sizeof(buffer)-2 || !ch)
983 if(ch) buffer[b] = 0;
997 else if(!strcmp(type.name, "bool"))
1004 else if(!strcmp(type.name, "SetBool"))
1006 if(value.i == SetBool::true)
1008 else if(value.i == SetBool::false)
1013 else if(type.type == enumClass)
1016 WriteNumber(f, type, value, indent);
1019 else if(eClass_IsDerived(type, class(Map)))
1021 WriteMap(f, type, value.p, indent);
1023 else if(eClass_IsDerived(type, class(Container)))
1025 WriteArray(f, type, value.p, indent);
1027 else if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
1029 _WriteJSONObject(f, type, value.p, indent);
1031 else if(eClass_IsDerived(type, class(ColorAlpha)))
1033 WriteColorAlpha(f, type, value, indent);
1035 else if(type.type == bitClass)
1038 dataType = eSystem_FindClass(__thisModule, type.dataTypeString);
1039 WriteNumber(f, dataType, value, indent);
1041 else if(type.type == systemClass || type.type == unitClass)
1043 WriteNumber(f, type, value, indent);
1048 public bool WriteJSONObject(File f, Class objectType, void * object, int indent)
1050 bool result = false;
1053 result = _WriteJSONObject(f, objectType, object, indent);
1059 static bool _WriteJSONObject(File f, Class objectType, void * object, int indent)
1063 const char * string = null;
1065 if(objectType._vTbl[__ecereVMethodID_class_OnGetString] != objectType.base._vTbl[__ecereVMethodID_class_OnGetString])
1069 string = ((const char *(*)())(void *)objectType._vTbl[__ecereVMethodID_class_OnGetString])(objectType, object, buffer, null, null);
1073 // TOCHECK: ProjectNode.ec why do we add quotes in OnGetString there?
1074 if(string[0] == '\"')
1087 bool isFirst = true;
1088 Class mapKeyClass = null, mapDataClass = null;
1090 List<Class> bases { };
1092 if(objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
1094 mapKeyClass = objectType.templateArgs[0].dataTypeClass;
1095 mapDataClass = objectType.templateArgs[2].dataTypeClass;
1101 for(baseClass = objectType; baseClass; baseClass = baseClass.base)
1103 if(baseClass.isInstanceClass || !baseClass.base)
1105 bases.Insert(null, baseClass);
1108 for(baseClass : bases)
1110 for(prop = baseClass.membersAndProperties.first; prop; prop = prop.next)
1112 if(prop.memberAccess != publicAccess || (prop.isProperty && (!prop.Set || !prop.Get))) continue;
1115 if(!prop.conversion && (!prop.IsSet || prop.IsSet(object)))
1117 DataValue value { };
1120 if(mapKeyClass && !strcmp(prop.name, "key"))
1122 else if(mapDataClass && !strcmp(prop.name, "value"))
1123 type = mapDataClass;
1125 type = eSystem_FindClass(__thisModule, prop.dataTypeString);
1127 type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
1129 PrintLn("warning: Unresolved data type ", (String)prop.dataTypeString);
1132 if(type.type == enumClass || type.type == bitClass || type.type == unitClass || type.type == systemClass)
1134 // TOFIX: How to swiftly handle classes with base data type?
1135 if(type == class(double) || !strcmp(type.dataTypeString, "double"))
1137 value.d = ((double (*)(void *))(void *)prop.Get)(object);
1139 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
1141 value.f = ((float (*)(void *))(void *)prop.Get)(object);
1143 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
1144 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
1146 value.ui64 = ((uint64 (*)(void *))(void *)prop.Get)(object);
1148 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
1149 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
1151 value.i = ((int (*)(void *))(void *)prop.Get)(object);
1153 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
1154 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
1155 !strcmp(type.dataTypeString, "int16"))
1157 value.s = ((short (*)(void *))(void *)prop.Get)(object);
1159 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
1160 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
1162 value.c = ((char (*)(void *))(void *)prop.Get)(object);
1165 else if(type.type == structClass)
1167 value.p = new0 byte[type.structSize];
1168 ((void (*)(void *, void *))(void *)prop.Get)(object, value.p);
1172 value.p = ((void *(*)(void *))(void *)prop.Get)(object);
1175 if(!isFirst) f.Puts(",\n");
1176 for(c = 0; c<indent; c++) f.Puts(" ");
1179 f.Putc((char)toupper(prop.name[0]));
1180 f.Puts(prop.name+1);
1182 WriteValue(f, type, value, indent);
1184 if(type.type == structClass)
1191 DataMember member = (DataMember)prop;
1192 DataValue value { };
1194 Class type = eSystem_FindClass(__thisModule, member.dataTypeString);
1196 type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
1198 offset = member._class.offset + member.offset;
1202 if(type.type == normalClass || type.type == noHeadClass || type.type == structClass || !strcmp(type.name, "String"))
1204 if(type.type == structClass)
1205 value.p = (void *)((byte *)object + offset);
1207 value.p = *(void **)((byte *)object + offset);
1211 else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
1213 value.d = *(double *)((byte *)object + offset);
1215 else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
1217 value.f = *(float *)((byte *)object + offset);
1219 else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
1220 !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
1222 value.ui64 = *(uint64 *)((byte *)object + offset);
1224 else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
1225 !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
1227 value.i = *(int *)((byte *)object + offset);
1228 if(!strcmp(type.name, "bool") || type.type == enumClass)
1232 else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
1233 !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
1234 !strcmp(type.dataTypeString, "int16"))
1236 value.s = *(short *)((byte *)object + offset);
1238 else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
1239 !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
1241 value.c = *(char *)((byte *)object + offset);
1245 value.i = *(int *)((byte *)object + offset);
1248 if(!isFirst) f.Puts(",\n");
1249 for(c = 0; c<indent; c++) f.Puts(" ");
1252 f.Putc((char)toupper(member.name[0]));
1253 f.Puts(member.name+1);
1255 WriteValue(f, type, value, indent);
1266 for(c = 0; c<indent; c++) f.Puts(" "); f.Puts("}");