namespace sys;
+import "instance"
import "System"
import "Array"
default:
-static void UnusedFunction()
+__attribute__((unused)) static void UnusedFunction()
{
int a;
a.OnGetDataFromString(null);
public enum SetBool : uint
{
- unset, false, true /*; // Syntax error! */
+ unset, false, true;
/*public property bool // NOT WORKING!
{
void SkipEmpty()
{
- while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'))
+ while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '/'))
{
f.Getc(&ch);
}
{
value.p = string;
}
- else if(type && type.type == enumClass)
+ else if(type && (type.type == enumClass || type.type == unitClass))
{
- if(type._vTbl[__ecereVMethodID_class_OnGetDataFromString](type, &value.i, string))
+ if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, &value.i, string))
result = success;
else
result = typeMismatch;
}
else if(type && (type.type == structClass))
{
- if(type._vTbl[__ecereVMethodID_class_OnGetDataFromString](type, value.p, string))
+ if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, value.p, string))
result = success;
else
result = typeMismatch;
else if(ch == '[')
{
Container array;
- result = GetArray(type, &array);
-
- if(type && eClass_IsDerived(type, class(Container)))
+ if(type && eClass_IsDerived(type, class(Map)))
+ {
+ result = GetMap(type, (Map *)&array);
+ }
+ else
+ result = GetArray(type, &array);
+
+ if(result == success && type && eClass_IsDerived(type, class(Container)))
{
value.p = array;
}
if(array)
array.Free();
delete array;
- result = typeMismatch;
+ if(result != success)
+ result = typeMismatch;
}
}
else if(ch == '-' || isdigit(ch))
}
else if(ch == '{')
{
- void * object;
+ void * object = value.p;
result = GetObject(type, &object);
if(result)
{
- if(type && (type.type == normalClass || type.type == structClass || type.type == noHeadClass || type.type == bitClass))
+ if(type && type.type == structClass);
+ else if(type && (type.type == normalClass || type.type == noHeadClass || type.type == bitClass))
{
value.p = object;
}
else
{
result = typeMismatch;
- type._vTbl[__ecereVMethodID_class_OnFree](object);
+ if(type)
+ ((void (*)(void *, void *))(void *)type._vTbl[__ecereVMethodID_class_OnFree])(type, object);
}
}
}
}
buffer[c] = 0;
result = success;
-
+
if(type)
- {
+ {
if(!strcmp(type.name, "bool"))
{
if(!strcmpi(buffer, "false")) value.i = 0;
else
result = typeMismatch;
}
- else if(!strcmpi(buffer, "null"))
+ else if(!strcmpi(buffer, "null"))
{
- value.p = 0;
+ if(type.type != structClass)
+ value.p = 0;
}
else
result = typeMismatch;
*array = null;
if(ch == '[')
{
- int count = 0;
*array = eInstance_New(type);
result = success;
while(result)
arrayType = type.templateArgs[0].dataTypeClass;
}
+ if(arrayType && arrayType.type == structClass)
+ value.p = new0 byte[arrayType.structSize];
itemResult = GetValue(arrayType, value);
if(itemResult == success)
{
uint64 t;
if(arrayType.type == structClass)
{
- t = (uint64) value.p;
+ t = (uint64)(uintptr)value.p;
}
else if(arrayType == class(double) || !strcmp(arrayType.dataTypeString, "double"))
{
- t = *(uint64 *)&value.d;
+ t = value.ui64; //*(uint64 *)&value.d;
}
else if(arrayType == class(float) || !strcmp(arrayType.dataTypeString, "float"))
{
- t = *(uint *)&value.f;
+ t = value.ui; //f*(uint *)&value.f;
}
- else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64")
+ else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64") ||
!strcmp(arrayType.dataTypeString, "unsigned int64") || !strcmp(arrayType.dataTypeString, "uint64"))
{
t = value.ui64;
}
- else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
+ else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
!strcmp(arrayType.dataTypeString, "unsigned int") || !strcmp(arrayType.dataTypeString, "uint"))
{
t = value.i;
}
- else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
- !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
+ else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
+ !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
!strcmp(arrayType.dataTypeString, "int16"))
{
t = value.s;
}
- else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
+ else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
!strcmp(arrayType.dataTypeString, "unsigned char") || !strcmp(arrayType.dataTypeString, "byte"))
{
t = value.c;
}
else
{
- t = (uint64)value.p;
+ t = (uint64)(uintptr)value.p;
}
((void *(*)(void *, uint64))(void *)array->Add)(*array, t);
+
+ if(arrayType && arrayType.type == structClass)
+ delete value.p;
}
else
{
if(itemResult == typeMismatch)
{
- PrintLn("Warning: Incompatible value for array value, expected ", (String)arrayType.name);
+ if(arrayType)
+ PrintLn("Warning: Incompatible value for array value, expected ", (String)arrayType.name);
}
else if(itemResult == noItem)
result = success;
}
}
}
- ch = 0;
+ ch = 0;
+ return result;
+ }
+
+ JSONResult GetMap(Class type, Map * map)
+ {
+ JSONResult result = syntaxError;
+ SkipEmpty();
+ *map = null;
+ if(ch == '[')
+ {
+ Class mapNodeType = type.templateArgs[0].dataTypeClass;
+ Class keyType = mapNodeType.templateArgs[0].dataTypeClass;
+ Property keyProp = null;
+ if(keyType && !strcmp(keyType.dataTypeString, "char *"))
+ keyProp = eClass_FindProperty(mapNodeType, "key", mapNodeType.module);
+
+ *map = eInstance_New(type);
+ result = success;
+
+ while(result)
+ {
+ DataValue value { };
+
+ JSONResult itemResult;
+
+ itemResult = GetValue(mapNodeType, value);
+ if(itemResult == success)
+ {
+ String s = keyProp ? ((void * (*)(void *))(void *)keyProp.Get)(value.p) : null;
+ ((void *(*)(void *, uint64))(void *)map->Add)(*map, (uint64)(uintptr)value.p);
+ // Must free String keys here
+ delete s;
+ }
+ else
+ {
+ if(itemResult == typeMismatch)
+ {
+ if(mapNodeType)
+ PrintLn("Warning: Incompatible value for array value, expected ", (String)mapNodeType.name);
+ }
+ else if(itemResult == noItem)
+ result = success;
+ else
+ result = itemResult;
+ }
+
+ if(result != syntaxError)
+ {
+ if(ch != ']' && ch != ',')
+ {
+ ch = 0;
+ SkipEmpty();
+ }
+ if(ch == ']')
+ {
+ break;
+ }
+ else if(ch != ',')
+ result = syntaxError;
+ }
+ }
+ }
+ ch = 0;
return result;
}
f.Getc(&unicode[0]);
f.Getc(&unicode[1]);
f.Getc(&unicode[2]);
- f.Getc(&unicode[3]);
+ f.Getc(&unicode[3]);
}
escaped = false;
}
result = success;
}
delete buffer;
- ch = 0;
+ if(ch != ',' && ch != '}')
+ ch = 0;
return result;
}
public JSONResult GetObject(Class objectType, void ** object)
{
JSONResult result = syntaxError;
- *object = null;
+ if(!objectType || objectType.type != structClass)
+ *object = null;
SkipEmpty();
if(ch == '{')
{
+ Class mapKeyClass = null, mapDataClass = null;
+
+ if(objectType && objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
+ {
+ mapKeyClass = objectType.templateArgs[0].dataTypeClass;
+ mapDataClass = objectType.templateArgs[2].dataTypeClass;
+ }
+
result = success;
- if(objectType && objectType.type == noHeadClass || objectType.type == normalClass)
+ if(objectType && (objectType.type == noHeadClass || objectType.type == normalClass))
{
*object = eInstance_New(objectType);
}
- else if(objectType)
+ else if(objectType && objectType.type != structClass)
{
*object = eSystem_New(objectType.typeSize);
}
ch = 0;
if(GetString(&string))
{
- bool found = true;
DataMember member = null;
Property prop = null;
Class type = null;
+ bool isKey = false;
+ uint offset = 0;
if(objectType)
{
string[0] = (char)tolower(string[0]);
- member = eClass_FindDataMember(objectType, string, objectType.module, null, null);
- if(member)
+ if(mapKeyClass && !strcmp(string, "key"))
{
- type = eSystem_FindClass(__thisModule, member.dataTypeString);
- if(!type)
- type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
+ prop = eClass_FindProperty(objectType, "key", objectType.module);
+ type = mapKeyClass;
+ isKey = true;
}
- else if(!member)
+ else if(mapDataClass && !strcmp(string, "value"))
+ {
+ prop = eClass_FindProperty(objectType, "value", objectType.module);
+ type = mapDataClass;
+ }
+ else
{
- prop = eClass_FindProperty(objectType, string, objectType.module);
- if(prop)
+ member = eClass_FindDataMember(objectType, string, objectType.module, null, null);
+ if(member)
{
- type = eSystem_FindClass(__thisModule, prop.dataTypeString);
+ type = eSystem_FindClass(__thisModule, member.dataTypeString);
if(!type)
- type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
+ type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
+
+ offset = member._class.offset + member.offset;
}
- else
- PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
- }
+ else if(!member)
+ {
+ prop = eClass_FindProperty(objectType, string, objectType.module);
+ if(prop)
+ {
+ type = eSystem_FindClass(__thisModule, prop.dataTypeString);
+ if(!type)
+ type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
+ }
+ else
+ PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
+ }
+ }
}
// Find Member in Object Class
{
if(type && type.type == structClass)
{
- value.p = (byte *)*object + member._class.offset + member.offset;
+ if(member)
+ {
+ value.p = (byte *)*object + offset;
+ memset(value.p, 0, type.structSize);
+ }
+ else if(prop)
+ {
+ value.p = new0 byte[type.structSize];
+ }
}
ch = 0;
SkipEmpty();
if(member)
{
// TOFIX: How to swiftly handle classes with base data type?
- if(type == class(double) || !strcmp(type.dataTypeString, "double"))
+ if(type.type == structClass)
+ ;
+ else if(type.type == normalClass || type.type == noHeadClass)
{
- *(double *)((byte *)*object + member._class.offset + member.offset) = value.d;
+ void ** ptr = (void**)((byte *)*object + offset);
+ if(eClass_IsDerived(type, class(Container)) && *ptr)
+ {
+ Container container = (Container)*ptr;
+ container.Free();
+ delete container;
+ }
+ *ptr = value.p;
+ }
+ else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
+ {
+ *(double *)((byte *)*object + offset) = value.d;
}
else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
{
- *(float *)((byte *)*object + member._class.offset + member.offset) = value.f;
+ *(float *)((byte *)*object + offset) = value.f;
}
- else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64")
+ else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
!strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
{
- *(uint64 *)((byte *)*object + member._class.offset + member.offset) = value.ui64;
+ *(uint64 *)((byte *)*object + offset) = value.ui64;
}
- else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
+ else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
!strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
{
- int * ptr = (int *)((byte *)*object + member._class.offset + member.offset);
- // TODO: Fix Me Up 64 bit pointer here
- if(eClass_IsDerived(type, class(Container)) && *ptr)
- {
- Container container = (Container)*ptr;
- container.Free();
- delete container;
- }
- *ptr = value.i;
+ *(int *)((byte *)*object + offset) = value.i;
}
- else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
- !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
+ else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
+ !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
!strcmp(type.dataTypeString, "int16"))
{
- *(short *)((byte *)*object + member._class.offset + member.offset) = value.s;
+ *(short *)((byte *)*object + offset) = value.s;
}
- else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
+ else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
!strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
{
- *(char *)((byte *)*object + member._class.offset + member.offset) = value.c;
+ *(char *)((byte *)*object + offset) = value.c;
}
- else if(type.type != structClass)
+ else
{
- *(void **)((byte *)*object + member._class.offset + member.offset) = value.p;
+ *(void **)((byte *)*object + offset) = value.p;
}
}
else if(prop && prop.Set)
{
if(!strcmp(type.dataTypeString, "char *"))
{
- ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
- delete value.p;
- }
- // TOFIX: How to swiftly handle classes with base data type?
- else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
- {
- ((void (*)(void *, double))(void *)prop.Set)(*object, value.d);
- }
- else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
- {
- ((void (*)(void *, float))(void *)prop.Set)(*object, value.f);
- }
- else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64")
- !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
- {
- ((void (*)(void *, uint64))(void *)prop.Set)(*object, value.ui64);
- }
- else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
- !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
- {
- ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
- }
- else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
- !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
- !strcmp(type.dataTypeString, "int16"))
- {
- ((void (*)(void *, short))(void *)prop.Set)(*object, value.s);
+ ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
+ if(!isKey)
+ delete value.p;
}
- else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
- !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
+ else if(type.type == enumClass || type.type == bitClass || type.type == unitClass || type.type == systemClass)
{
- ((void (*)(void *, char))(void *)prop.Set)(*object, value.c);
+ // TOFIX: How to swiftly handle classes with base data type?
+ if(type == class(double) || !strcmp(type.dataTypeString, "double"))
+ {
+ ((void (*)(void *, double))(void *)prop.Set)(*object, value.d);
+ }
+ else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
+ {
+ ((void (*)(void *, float))(void *)prop.Set)(*object, value.f);
+ }
+ else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
+ !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
+ {
+ ((void (*)(void *, uint64))(void *)prop.Set)(*object, value.ui64);
+ }
+ else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
+ !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
+ {
+ ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
+ }
+ else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
+ !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
+ !strcmp(type.dataTypeString, "int16"))
+ {
+ ((void (*)(void *, short))(void *)prop.Set)(*object, value.s);
+ }
+ else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
+ !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
+ {
+ ((void (*)(void *, char))(void *)prop.Set)(*object, value.c);
+ }
+ else
+ {
+ ((void (*)(void *, int))(void *)prop.Set)(*object, value.i);
+ }
}
else
{
}
else
result = syntaxError;
+
+ if(prop && type.type == structClass)
+ {
+ delete value.p;
+ }
}
}
- else if(ch)
+ else if(ch && ch != '}' && ch != ',')
result = syntaxError;
delete string;
}
buffer[c] = 0;
//if(strchr(buffer, '.'))
+ if(!type) return success;
// TOFIX: How to swiftly handle classes with base data type?
if(type == class(double) || !strcmp(type.dataTypeString, "double"))
}
else if(type == class(uint64) || !strcmp(type.dataTypeString, "uint64"))
{
- value.ui64 = strtol(buffer, null, 10); // TOFIX: 64 bit support
+ value.ui64 = strtoul(buffer, null, 10); // TOFIX: 64 bit support
+ result = success;
+ }
+ else if(type == class(uint) || !strcmp(type.dataTypeString, "unsigned int"))
+ {
+ value.ui = (uint)strtoul(buffer, null, 10); // TOFIX: 64 bit support
result = success;
}
else
{
- value.i = strtol(buffer, null, 10);
+ value.i = (int)strtol(buffer, null, 10);
result = success;
}
+
+ if(result == success && type.type == unitClass)
+ {
+ // Convert to reference unit
+ Property prop;
+ for(prop = type.conversions.first; prop; prop = prop.next)
+ {
+ bool refProp = false;
+ Class c;
+ if(!strcmp(prop.name, type.base.fullName))
+ refProp = true;
+ else if( (c = eSystem_FindClass(type.module, prop.name) ) )
+ {
+ Property p;
+ for(p = c.conversions.first; p; p = p.next)
+ {
+ if(!strcmp(p.name, type.base.fullName) && !p.Set && !p.Get)
+ {
+ refProp = true;
+ break;
+ }
+ }
+ }
+ if(refProp)
+ {
+ if(prop.Set && prop.Get)
+ {
+ const String dts = type.base.dataTypeString;
+ if(!strcmp(dts, "double"))
+ value.d = ((double(*)(double))(void *)prop.Get)(value.d);
+ else if(!strcmp(dts, "float"))
+ value.f = ((float(*)(float))(void *)prop.Get)(value.f);
+ else if(!strcmp(dts, "int"))
+ value.i = ((int(*)(int))(void *)prop.Get)(value.i);
+ else if(!strcmp(dts, "int64"))
+ value.i64 = ((int64(*)(int64))(void *)prop.Get)(value.i64);
+ else if(!strcmp(dts, "unsigned int"))
+ value.ui = ((uint(*)(uint))(void *)prop.Get)(value.ui);
+ else if(!strcmp(dts, "uint64"))
+ value.ui64 = ((uint64(*)(uint64))(void *)prop.Get)(value.ui64);
+ }
+ else
+ break;
+ }
+ }
+ }
return result;
}
}
+bool WriteMap(File f, Class type, Map map, int indent)
+{
+ if(map)
+ {
+ int i;
+ bool isFirst = true;
+ MapIterator it { map = map };
+ Class mapNodeClass = map._class.templateArgs[0].dataTypeClass;
+ f.Puts("[\n");
+ indent++;
+
+ while(it.Next())
+ {
+ MapNode n = (MapNode)it.pointer;
+ if(!isFirst)
+ f.Puts(",\n");
+ else
+ isFirst = false;
+ for(i = 0; i<indent; i++) f.Puts(" ");
+ _WriteJSONObject(f, mapNodeClass, n, indent);
+ }
+ f.Puts("\n");
+ indent--;
+ for(i = 0; i<indent; i++) f.Puts(" ");
+ f.Puts("]");
+ }
+ else
+ f.Puts("null");
+ return true;
+}
+
bool WriteArray(File f, Class type, Container array, int indent)
{
if(array)
{
- int c;
int i;
bool isFirst = true;
Iterator it { array };
Class arrayType = type.templateArgs[0].dataTypeClass;
f.Puts("[\n");
indent++;
-
+
while(it.Next())
{
- byte * pointer;
DataValue value { };
uint64 t = ((uint64(*)(void *, void *))(void *)array.GetData)(array, it.pointer);
if(!isFirst)
f.Puts(",\n");
else
- isFirst = false;
-
+ isFirst = false;
+
// Add value
// TODO: Verify the matching between template type and uint64
if(arrayType.type == structClass)
{
- value.p = (void *)t;
+ value.p = (void *)(uintptr)t;
}
else if(arrayType == class(double) || !strcmp(arrayType.dataTypeString, "double"))
{
- value.d = *(double *)&t;
+ value.ui64 = t;
+ //value.d = *(double *)&t;
}
else if(arrayType == class(float) || !strcmp(arrayType.dataTypeString, "float"))
{
- value.f = *(float *)&t;
+ value.ui = (uint)t;
+ //value.f = *(float *)&t;
}
- else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64")
+ else if(arrayType.typeSize == sizeof(int64) || !strcmp(arrayType.dataTypeString, "int64") ||
!strcmp(arrayType.dataTypeString, "unsigned int64") || !strcmp(arrayType.dataTypeString, "uint64"))
{
value.ui64 = t;
}
- else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
+ else if(arrayType.typeSize == sizeof(int) || !strcmp(arrayType.dataTypeString, "int") ||
!strcmp(arrayType.dataTypeString, "unsigned int") || !strcmp(arrayType.dataTypeString, "uint"))
{
value.i = (int)t;
}
- else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
- !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
+ else if(arrayType.typeSize == sizeof(short int) || !strcmp(arrayType.dataTypeString, "short") ||
+ !strcmp(arrayType.dataTypeString, "unsigned short") || !strcmp(arrayType.dataTypeString, "uint16") ||
!strcmp(arrayType.dataTypeString, "int16"))
{
value.s = (short)t;
}
- else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
+ else if(arrayType.typeSize == sizeof(byte) || !strcmp(arrayType.dataTypeString, "char") ||
!strcmp(arrayType.dataTypeString, "unsigned char") || !strcmp(arrayType.dataTypeString, "byte"))
{
value.c = (char)t;
}
else
{
- value.p = (void *)t;
+ value.p = (void *)(uintptr)t;
}
for(i = 0; i<indent; i++) f.Puts(" ");
WriteValue(f, arrayType, value, indent);
- }
+ }
f.Puts("\n");
indent--;
for(i = 0; i<indent; i++) f.Puts(" ");
- f.Puts("]");
+ f.Puts("]");
}
else
f.Puts("null");
{
char buffer[1024];
bool needClass = false;
+ bool quote;
buffer[0] = 0;
if(type == class(double) || !strcmp(type.dataTypeString, "double"))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.d, buffer, 0, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.d, buffer, 0, &needClass);
else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.f, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.f, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "int64"))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.i64, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.i64, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64") || type.typeSize == sizeof(int64))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.ui64, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui64, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "int"))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.i, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.i, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint") || type.typeSize == sizeof(int))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.ui, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "short") || !strcmp(type.dataTypeString, "int16"))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.s, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.s, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") || type.typeSize == sizeof(short int))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.us, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.us, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "char"))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.c, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.c, buffer, null, &needClass);
else if(!strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte") || type.typeSize == sizeof(byte))
- type._vTbl[__ecereVMethodID_class_OnGetString](type, &value.uc, buffer, null, &needClass);
+ ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.uc, buffer, null, &needClass);
+
+ quote = (type.type == unitClass && ((buffer[0] != '.' && !isdigit(buffer[0])) || strchr(buffer, ' ')));
+ if(quote) f.Puts("\"");
f.Puts(buffer);
+ if(quote) f.Puts("\"");
return true;
}
{
if(!strcmp(type.name, "String") || !strcmp(type.dataTypeString, "char *"))
{
- f.Puts("\"");
- //if(strchr(value.p, '\"') || strchr(value.p, '\\'))
+ if(!value.p)
+ f.Puts("null");
+ else
{
- int c = 0;
- int b = 0;
- char buffer[1024];
- char * string = value.p;
- char ch;
- while(true)
+ f.Puts("\"");
+ //if(strchr(value.p, '\"') || strchr(value.p, '\\'))
{
- ch = string[c++];
- if(ch == '\"')
+ int c = 0;
+ int b = 0;
+ char buffer[1024];
+ char * string = value.p;
+ char ch;
+ while(true)
{
- buffer[b] = 0;
- f.Puts(buffer);
- f.Puts("\\\"");
- b = 0;
- }
- else if(ch == '\\')
- {
- buffer[b] = 0;
- f.Puts(buffer);
- f.Puts("\\\\");
- b = 0;
- }
- else if(b == sizeof(buffer)-2 || !ch)
- {
- buffer[b++] = ch;
- if(ch) buffer[b] = 0;
- f.Puts(buffer);
- b = 0;
- if(!ch) break;
+ ch = string[c++];
+ if(ch == '\"')
+ {
+ buffer[b] = 0;
+ f.Puts(buffer);
+ f.Puts("\\\"");
+ b = 0;
+ }
+ else if(ch == '\\')
+ {
+ buffer[b] = 0;
+ f.Puts(buffer);
+ f.Puts("\\\\");
+ b = 0;
+ }
+ else if(b == sizeof(buffer)-2 || !ch)
+ {
+ buffer[b++] = ch;
+ if(ch) buffer[b] = 0;
+ f.Puts(buffer);
+ b = 0;
+ if(!ch) break;
+ }
+ else
+ buffer[b++] = ch;
}
- else
- buffer[b++] = ch;
}
+ /*else
+ f.Puts(value.p);*/
+ f.Puts("\"");
}
- /*else
- f.Puts(value.p);*/
- f.Puts("\"");
}
else if(!strcmp(type.name, "bool"))
{
else if(type.type == enumClass)
{
f.Puts("\"");
- WriteNumber(f, type, value, indent);
+ WriteNumber(f, type, value, indent);
f.Puts("\"");
}
+ else if(eClass_IsDerived(type, class(Map)))
+ {
+ WriteMap(f, type, value.p, indent);
+ }
else if(eClass_IsDerived(type, class(Container)))
{
WriteArray(f, type, value.p, indent);
}
- else if(type.type == normalClass || type.type == noHeadClass || type.type == structClass || type.type == bitClass)
+ else if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
{
- WriteJSONObject(f, type, value.p, indent);
+ _WriteJSONObject(f, type, value.p, indent);
}
- else if(type.type == systemClass)
+ else if(type.type == bitClass)
+ {
+ Class dataType;
+ dataType = eSystem_FindClass(__thisModule, type.dataTypeString);
+ WriteNumber(f, dataType, value, indent);
+ }
+ else if(type.type == systemClass || type.type == unitClass)
{
WriteNumber(f, type, value, indent);
}
public bool WriteJSONObject(File f, Class objectType, void * object, int indent)
{
+ bool result = false;
if(object)
{
- char * string = null;
+ result = _WriteJSONObject(f, objectType, object, indent);
+ f.Puts("\n");
+ }
+ return result;
+}
+
+static bool _WriteJSONObject(File f, Class objectType, void * object, int indent)
+{
+ if(object)
+ {
+ const char * string = null;
if(objectType._vTbl[__ecereVMethodID_class_OnGetString] != objectType.base._vTbl[__ecereVMethodID_class_OnGetString])
{
char buffer[1024];
buffer[0] = 0;
- string = ((char *(*)())(void *)objectType._vTbl[__ecereVMethodID_class_OnGetString])(objectType, object, buffer, null, null);
+ string = ((const char *(*)())(void *)objectType._vTbl[__ecereVMethodID_class_OnGetString])(objectType, object, buffer, null, null);
}
if(string)
{
Property prop;
int c;
bool isFirst = true;
-
+ Class mapKeyClass = null, mapDataClass = null;
+ Class baseClass;
+ List<Class> bases { };
+
+ if(objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
+ {
+ mapKeyClass = objectType.templateArgs[0].dataTypeClass;
+ mapDataClass = objectType.templateArgs[2].dataTypeClass;
+ }
+
f.Puts("{\n");
indent++;
- for(prop = objectType.membersAndProperties.first; prop; prop = prop.next)
+ for(baseClass = objectType; baseClass; baseClass = baseClass.base)
+ {
+ if(baseClass.isInstanceClass || !baseClass.base)
+ break;
+ bases.Insert(null, baseClass);
+ }
+
+ for(baseClass : bases)
{
- if(prop.memberAccess != publicAccess || (prop.isProperty && (!prop.Set || !prop.Get))) continue;
- if(prop.isProperty)
+ for(prop = baseClass.membersAndProperties.first; prop; prop = prop.next)
{
- if(!prop.conversion && (!prop.IsSet || prop.IsSet(object)))
+ if(prop.memberAccess != publicAccess || (prop.isProperty && (!prop.Set || !prop.Get))) continue;
+ if(prop.isProperty)
{
- DataValue value { };
- Class type = eSystem_FindClass(__thisModule, prop.dataTypeString);
- if(!type)
- type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
-
- // TOFIX: How to swiftly handle classes with base data type?
- if(type == class(double) || !strcmp(type.dataTypeString, "double"))
- {
- value.d = ((double (*)(void *))(void *)prop.Get)(object);
- }
- else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
- {
- value.f = ((float (*)(void *))(void *)prop.Get)(object);
- }
- else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64")
- !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
- {
- value.ui64 = ((uint64 (*)(void *))(void *)prop.Get)(object);
- }
- else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
- !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
- {
- value.i = ((int (*)(void *))(void *)prop.Get)(object);
- }
- else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
- !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
- !strcmp(type.dataTypeString, "int16"))
- {
- value.s = ((short (*)(void *))(void *)prop.Get)(object);
- }
- else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
- !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
+ if(!prop.conversion && (!prop.IsSet || prop.IsSet(object)))
{
- value.c = ((char (*)(void *))(void *)prop.Get)(object);
- }
- else
- {
- value.p = ((void *(*)(void *))(void *)prop.Get)(object);
- }
+ DataValue value { };
+ Class type;
- if(!isFirst) f.Puts(",\n");
- for(c = 0; c<indent; c++) f.Puts(" ");
+ if(mapKeyClass && !strcmp(prop.name, "key"))
+ type = mapKeyClass;
+ else if(mapDataClass && !strcmp(prop.name, "value"))
+ type = mapDataClass;
+ else
+ type = eSystem_FindClass(__thisModule, prop.dataTypeString);
+ if(!type)
+ type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
+ if(!type)
+ PrintLn("warning: Unresolved data type ", (String)prop.dataTypeString);
+ else
+ {
+ // TOFIX: How to swiftly handle classes with base data type?
+ if(type == class(double) || !strcmp(type.dataTypeString, "double"))
+ {
+ value.d = ((double (*)(void *))(void *)prop.Get)(object);
+ }
+ else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
+ {
+ value.f = ((float (*)(void *))(void *)prop.Get)(object);
+ }
+ else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
+ !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
+ {
+ value.ui64 = ((uint64 (*)(void *))(void *)prop.Get)(object);
+ }
+ else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
+ !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
+ {
+ value.i = ((int (*)(void *))(void *)prop.Get)(object);
+ }
+ else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
+ !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
+ !strcmp(type.dataTypeString, "int16"))
+ {
+ value.s = ((short (*)(void *))(void *)prop.Get)(object);
+ }
+ else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
+ !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
+ {
+ value.c = ((char (*)(void *))(void *)prop.Get)(object);
+ }
+ else if(type.type == structClass)
+ {
+ value.p = new0 byte[type.structSize];
+ ((void (*)(void *, void *))(void *)prop.Get)(object, value.p);
+ }
+ else
+ {
+ value.p = ((void *(*)(void *))(void *)prop.Get)(object);
+ }
- f.Puts("\"");
- f.Putc((char)toupper(prop.name[0]));
- f.Puts(prop.name+1);
- f.Puts("\" : ");
- WriteValue(f, type, value, indent);
- isFirst = false;
- }
- }
- else
- {
- DataMember member = (DataMember)prop;
- DataValue value { };
- Class type = eSystem_FindClass(__thisModule, member.dataTypeString);
- if(!type)
- type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
+ if(!isFirst) f.Puts(",\n");
+ for(c = 0; c<indent; c++) f.Puts(" ");
- if(type)
- {
- if(type.type == normalClass || type.type == noHeadClass || type.type == structClass || !strcmp(type.name, "String"))
- {
- if(type.type == structClass)
- value.p = (void *)((byte *)object + member._class.offset + member.offset);
- else
- value.p = *(void **)((byte *)object + member._class.offset + member.offset);
- if(!value.p)
- continue;
- }
- else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
- {
- value.d = *(double *)((byte *)object + member._class.offset + member.offset);
- }
- else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
- {
- value.f = *(float *)((byte *)object + member._class.offset + member.offset);
- }
- else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64")
- !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
- {
- value.ui64 = *(uint64 *)((byte *)object + member._class.offset + member.offset);
+ f.Puts("\"");
+ f.Putc((char)toupper(prop.name[0]));
+ f.Puts(prop.name+1);
+ f.Puts("\" : ");
+ WriteValue(f, type, value, indent);
+ isFirst = false;
+ if(type.type == structClass)
+ delete value.p;
+ }
}
- else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
- !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
+ }
+ else
+ {
+ DataMember member = (DataMember)prop;
+ DataValue value { };
+ uint offset;
+ Class type = eSystem_FindClass(__thisModule, member.dataTypeString);
+ if(!type)
+ type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
+
+ offset = member._class.offset + member.offset;
+
+ if(type)
{
- value.i = *(int *)((byte *)object + member._class.offset + member.offset);
- if(!strcmp(type.name, "bool") || type.type == enumClass)
- if(!value.i)
+ if(type.type == normalClass || type.type == noHeadClass || type.type == structClass || !strcmp(type.name, "String"))
+ {
+ if(type.type == structClass)
+ value.p = (void *)((byte *)object + offset);
+ else
+ value.p = *(void **)((byte *)object + offset);
+ if(!value.p)
continue;
- }
- else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
- !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
- !strcmp(type.dataTypeString, "int16"))
- {
- value.s = *(short *)((byte *)object + member._class.offset + member.offset);
- }
- else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
- !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
- {
- value.c = *(char *)((byte *)object + member._class.offset + member.offset);
- }
- else
- {
- value.i = *(int *)((byte *)object + member._class.offset + member.offset);
- }
+ }
+ else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
+ {
+ value.d = *(double *)((byte *)object + offset);
+ }
+ else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
+ {
+ value.f = *(float *)((byte *)object + offset);
+ }
+ else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
+ !strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
+ {
+ value.ui64 = *(uint64 *)((byte *)object + offset);
+ }
+ else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
+ !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
+ {
+ value.i = *(int *)((byte *)object + offset);
+ if(!strcmp(type.name, "bool") || type.type == enumClass)
+ if(!value.i)
+ continue;
+ }
+ else if(type.typeSize == sizeof(short int) || !strcmp(type.dataTypeString, "short") ||
+ !strcmp(type.dataTypeString, "unsigned short") || !strcmp(type.dataTypeString, "uint16") ||
+ !strcmp(type.dataTypeString, "int16"))
+ {
+ value.s = *(short *)((byte *)object + offset);
+ }
+ else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
+ !strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
+ {
+ value.c = *(char *)((byte *)object + offset);
+ }
+ else
+ {
+ value.i = *(int *)((byte *)object + offset);
+ }
- if(!isFirst) f.Puts(",\n");
- for(c = 0; c<indent; c++) f.Puts(" ");
+ if(!isFirst) f.Puts(",\n");
+ for(c = 0; c<indent; c++) f.Puts(" ");
- f.Puts("\"");
- f.Putc((char)toupper(member.name[0]));
- f.Puts(member.name+1);
- f.Puts("\" : ");
- WriteValue(f, type, value, indent);
- isFirst = false;
+ f.Puts("\"");
+ f.Putc((char)toupper(member.name[0]));
+ f.Puts(member.name+1);
+ f.Puts("\" : ");
+ WriteValue(f, type, value, indent);
+ isFirst = false;
+ }
}
}
- }
+ }
+
+ delete bases;
indent--;
f.Puts("\n");