namespace sys;
+import "instance"
import "System"
import "Array"
};
+public class ECONParser : JSONParser
+{
+ eCON = true;
+}
+
public class JSONParser
{
public:
File f;
+private:
char ch;
+ bool eCON;
void SkipEmpty()
{
- while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'))
+ if(eCON)
+ {
+ char pch;
+ bool lineComment = false;
+ bool comment = false;
+ while(!f.Eof() && (!ch || lineComment || comment || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '/'))
+ {
+ pch = ch;
+ f.Getc(&ch);
+ if(!lineComment && !comment && pch == '/')
+ {
+ if(ch == '/')
+ lineComment = true;
+ else if(ch == '*')
+ comment = true;
+ }
+ else if(lineComment && ch == '\n')
+ lineComment = false;
+ else if(comment && pch == '*' && ch == '/')
+ comment = false;
+ }
+ }
+ else
+ {
+ while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == '/'))
+ {
+ f.Getc(&ch);
+ }
+ }
+ }
+
+ void SkipExtraSemicolon()
+ {
+ while(!f.Eof() && (!ch || ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t' || ch == ';'))
{
f.Getc(&ch);
}
result = success;
delete string;
}
+ else if(type && eClass_IsDerived(type, class(ColorAlpha)))
+ {
+ result = GetColorAlpha(string, value);
+ delete string;
+ }
else if(type && (type.type == structClass))
{
if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, value.p, string))
if(array)
array.Free();
delete array;
- if(result != success)
- result = typeMismatch;
}
}
else if(ch == '-' || isdigit(ch))
}
else if(ch == '{')
{
- void * object = value.p;
- result = GetObject(type, &object);
- if(result)
+ if(type.type == structClass || type.type == normalClass || type.type == noHeadClass)
{
- if(type && type.type == structClass);
- else if(type && (type.type == normalClass || type.type == noHeadClass || type.type == bitClass))
+ void * object = value.p;
+ result = GetObject(type, &object);
+ if(result)
{
- value.p = object;
+ if(type && type.type == structClass);
+ else
+ value.p = object;
}
- else
+ }
+ else if(type.type == bitClass)
+ {
+ uint64 object = 0;
+ result = GetObject(type, (void **)&object);
+ if(result)
+ value.ui64 = object;
+ }
+ else
+ {
+ void * object = value.p;
+ result = GetObject(type, &object);
+ if(result)
{
result = typeMismatch;
if(type)
}
}
}
- else if(isalpha(ch))
+ else if(isalpha(ch) || ch == '_')
{
- char buffer[256];
- int c = 0;
- while(c < sizeof(buffer)-1 && isalpha(ch))
- {
- buffer[c++] = ch;
- if(!f.Getc(&ch)) break;
- }
- buffer[c] = 0;
- result = success;
-
- if(type)
+ if(eCON)
{
- if(!strcmp(type.name, "bool"))
+ String string;
+ if(GetIdentifier(&string, null))
{
- if(!strcmpi(buffer, "false")) value.i = 0;
- else if(!strcmpi(buffer, "true")) value.i = 1;
+ result = success;
+ if(eCON && type && (type.type == enumClass || type.type == unitClass))
+ {
+ // should this be set by calling __ecereVMethodID_class_OnGetDataFromString ?
+ if(((bool (*)(void *, void *, const char *))(void *)type._vTbl[__ecereVMethodID_class_OnGetDataFromString])(type, &value.i, string))
+ result = success;
+ else
+ result = typeMismatch;
+ }
+ else if(type && !strcmp(type.name, "bool"))
+ {
+ if(!strcmpi(string, "false")) value.i = 0;
+ else if(!strcmpi(string, "true")) value.i = 1;
+ else
+ result = typeMismatch;
+ }
+ else if(type && !strcmp(type.name, "SetBool"))
+ {
+ if(!strcmpi(string, "false")) value.i = SetBool::false;
+ else if(!strcmpi(string, "true")) value.i = SetBool::true;
+ else
+ result = typeMismatch;
+ }
+ else if(type && !strcmpi(string, "null"))
+ {
+ if(type.type != structClass)
+ value.p = 0;
+ }
+ else if(isSubclass(type, string))
+ {
+ void * object = value.p;
+ Class subtype = superFindClass(string, type.module);
+ SkipEmpty();
+ result = GetObject(subtype, &object);
+ if(result)
+ {
+ if(subtype && subtype.type == structClass);
+ else if(subtype && (subtype.type == normalClass || subtype.type == noHeadClass || subtype.type == bitClass))
+ {
+ value.p = object;
+ }
+ else
+ {
+ result = typeMismatch;
+ if(subtype)
+ ((void (*)(void *, void *))(void *)subtype._vTbl[__ecereVMethodID_class_OnFree])(subtype, object);
+ }
+ }
+ }
else
result = typeMismatch;
}
- else if(!strcmp(type.name, "SetBool"))
+ delete string;
+ }
+ else
+ {
+ char buffer[256];
+ int c = 0;
+ while(c < sizeof(buffer)-1 && (isalpha(ch) || isdigit(ch) || ch == '_'))
{
- if(!strcmpi(buffer, "false")) value.i = SetBool::false;
- else if(!strcmpi(buffer, "true")) value.i = SetBool::true;
- else
- result = typeMismatch;
+ buffer[c++] = ch;
+ if(!f.Getc(&ch)) break;
}
- else if(!strcmpi(buffer, "null"))
+ buffer[c] = 0;
+ result = success;
+
+ if(type)
{
- value.p = 0;
+ if(!strcmp(type.name, "bool"))
+ {
+ if(!strcmpi(buffer, "false")) value.i = 0;
+ else if(!strcmpi(buffer, "true")) value.i = 1;
+ else
+ result = typeMismatch;
+ }
+ else if(!strcmp(type.name, "SetBool"))
+ {
+ if(!strcmpi(buffer, "false")) value.i = SetBool::false;
+ else if(!strcmpi(buffer, "true")) value.i = SetBool::true;
+ else
+ result = typeMismatch;
+ }
+ else if(!strcmpi(buffer, "null"))
+ {
+ if(type.type != structClass)
+ value.p = 0;
+ }
+ else
+ result = typeMismatch;
}
else
result = typeMismatch;
}
- else
- result = typeMismatch;
}
else if(ch == '}' || ch == ']')
result = noItem;
+ if(result == typeMismatch)
+ PrintLn("Warning: Value type mismatch");
return result;
}
arrayType = type.templateArgs[0].dataTypeClass;
}
+ if(arrayType && arrayType.type == structClass)
+ value.p = new0 byte[arrayType.structSize];
itemResult = GetValue(arrayType, value);
if(itemResult == success)
{
t = (uint64)(uintptr)value.p;
}
((void *(*)(void *, uint64))(void *)array->Add)(*array, t);
+
+ if(arrayType && arrayType.type == structClass)
+ delete value.p;
}
else
{
return result;
}
+ JSONResult GetIdentifier(String * string, bool * wasQuoted)
+ {
+ JSONResult result = syntaxError;
+ Array<char> buffer { minAllocSize = 256 };
+ bool comment = false;
+ bool quoted = false;
+
+ *string = null;
+ SkipEmpty();
+ if(ch == '\"')
+ quoted = true;
+ else
+ buffer.Add(ch);
+ result = success;
+ while(f.Getc(&ch))
+ {
+ if(!comment && ch == '/')
+ {
+ if(f.Getc(&ch))
+ {
+ if(ch == '/')
+ break;
+ else if(ch == '*')
+ comment = true;
+ else
+ {
+ result = syntaxError;
+ break;
+ }
+ }
+ else
+ {
+ result = syntaxError;
+ break;
+ }
+ }
+ else if(comment && ch == '*')
+ {
+ if(f.Getc(&ch))
+ {
+ if(ch == '/')
+ {
+ comment = false;
+ ch = 0;
+ }
+ }
+ else
+ {
+ result = syntaxError;
+ break;
+ }
+ }
+ else if(ch == '\"' || (!quoted && !comment && ch && !isalpha(ch) && !isdigit(ch) && ch != '_'))
+ {
+ if(quoted && ch == '\"' && wasQuoted)
+ *wasQuoted = true;
+ break;
+ }
+ else if(!comment && ch)
+ {
+ buffer.Add(ch);
+ if(buffer.minAllocSize < buffer.count)
+ buffer.minAllocSize *= 2;
+ }
+ }
+ if(result != syntaxError)
+ {
+ buffer.Add(0);
+ *string = CopyString(buffer.array);
+ }
+ delete buffer;
+ if(ch != ',' && ch != '}' && ch != ';' && ch != '/' && ch != '=' && ch != ':')
+ ch = 0;
+ return result;
+ }
+
JSONResult GetString(String * string)
{
JSONResult result = syntaxError;
*string = null;
SkipEmpty();
- if(ch == '\"')
+ if(ch == '\"' || eCON)
{
while(f.Getc(&ch))
{
}
escaped = false;
}
- else if(ch == '\"')
+ else if(eCON && ch == '\"')
+ {
+ int seekback = 0;
+ char pch;
+ bool lineComment = false;
+ bool comment = false;
+ while(!f.Eof())
+ {
+ pch = ch;
+ f.Getc(&ch);
+ seekback--;
+ if(!lineComment && !comment && pch == '/')
+ {
+ if(ch == '/')
+ lineComment = true;
+ else if(ch == '*')
+ comment = true;
+ }
+ else if(lineComment && ch == '\n')
+ lineComment = false;
+ else if(comment && pch == '*' && ch == '/')
+ comment = false;
+ else if(ch == '=' || ch == ':' || ch == ';' || ch == ',' || ch == ']' || ch == '}')
+ {
+ ch = 0;
+ seekback = -1;
+ break;
+ }
+ else if(ch == '\"')
+ {
+ seekback = 0;
+ ch = 0;
+ break;
+ }
+ }
+ if(seekback != 0)
+ {
+ f.Seek(seekback, current);
+ break;
+ }
+ }
+ else if((!eCON && ch == '\"'))
{
break;
}
- buffer.Add(ch);
- if(buffer.minAllocSize < buffer.count)
- buffer.minAllocSize *= 2;
+ if(ch)
+ {
+ buffer.Add(ch);
+ if(buffer.minAllocSize < buffer.count)
+ buffer.minAllocSize *= 2;
+ }
}
}
buffer.Add(0);
result = success;
}
delete buffer;
- if(ch != ',' && ch != '}')
+ if(ch != ',' && ch != '}' && (!eCON || (ch != ';' && ch != '/')))
ch = 0;
return result;
}
{
JSONResult result = syntaxError;
if(!objectType || objectType.type != structClass)
- *object = null;
+ {
+ if(objectType && objectType.type == bitClass)
+ *(uint64 *)object = 0;
+ else
+ *object = null;
+ }
SkipEmpty();
if(ch == '{')
{
Class mapKeyClass = null, mapDataClass = null;
+ Class curClass = null;
+ DataMember curMember = null;
+ DataMember subMemberStack[256];
+ int subMemberStackPos = 0;
+ uint64 bits = 0;
+
+ if(objectType.type == bitClass)
+ {
+ switch(objectType.typeSize)
+ {
+ case 1: bits = (byte )*(uint64 *)object; break;
+ case 2: bits = (uint16)*(uint64 *)object; break;
+ case 4: bits = (uint32)*(uint64 *)object; break;
+ case 8: bits = (uint64)*(uint64 *)object; break;
+ }
+ }
if(objectType && objectType.templateClass && eClass_IsDerived(objectType.templateClass, class(MapNode)))
{
result = success;
if(objectType && (objectType.type == noHeadClass || objectType.type == normalClass))
- {
*object = eInstance_New(objectType);
- }
- else if(objectType && objectType.type != structClass)
- {
- *object = eSystem_New(objectType.typeSize);
- }
while(result)
{
String string;
+ bool wasQuoted = false;
+ int seek;
ch = 0;
- if(GetString(&string))
+ if(eCON)
+ {
+ SkipExtraSemicolon();
+ if(ch == '}')
+ break;
+ }
+ SkipEmpty();
+ seek = f.Tell();
+ if(eCON ? GetIdentifier(&string, &wasQuoted) : GetString(&string))
{
DataMember member = null;
Property prop = null;
Class type = null;
bool isKey = false;
+ bool isTemplateArg = false;
uint offset = 0;
+ if(eCON)
+ {
+ SkipEmpty();
+ prop = null; member = null;
+ if(ch == '=' || ch == ':')
+ {
+ if(wasQuoted)
+ string[0] = (char)tolower(string[0]);
+ while(1)
+ {
+ eClass_FindNextMember(objectType, &curClass, &curMember, subMemberStack, &subMemberStackPos);
+ if(!curMember) break;
+ if(!strcmp(curMember.name, string))
+ break;
+ }
+ }
+ else
+ eClass_FindNextMember(objectType, &curClass, &curMember, subMemberStack, &subMemberStackPos);
+ if(curMember)
+ {
+ prop = curMember.isProperty ? (Property)curMember : null;
+ member = curMember.isProperty ? null : curMember;
- if(objectType)
+ if(mapKeyClass && !strcmp(prop ? prop.name : member.name, "key"))
+ {
+ type = mapKeyClass;
+ isTemplateArg = true;
+ isKey = true;
+ }
+ else if(mapDataClass && !strcmp(prop ? prop.name : member.name, "value"))
+ {
+ type = mapDataClass;
+ isTemplateArg = true;
+ if(member)
+ offset = member._class.offset + member.offset;
+ }
+ else if(prop)
+ type = superFindClass(prop.dataTypeString, objectType.module);
+ else if(member)
+ {
+ type = superFindClass(member.dataTypeString, objectType.module);
+ offset = member._class.offset + member.offset;
+ }
+ }
+ else
+ {
+ if(ch == '=' || ch == ':')
+ PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
+ else
+ PrintLn("Warning: default member assignment: no more members");
+ }
+ }
+ if(objectType && !eCON)
{
string[0] = (char)tolower(string[0]);
if(mapKeyClass && !strcmp(string, "key"))
{
prop = eClass_FindProperty(objectType, "key", objectType.module);
type = mapKeyClass;
+ isTemplateArg = true;
isKey = true;
}
else if(mapDataClass && !strcmp(string, "value"))
{
prop = eClass_FindProperty(objectType, "value", objectType.module);
type = mapDataClass;
+ isTemplateArg = true;
}
else
{
member = eClass_FindDataMember(objectType, string, objectType.module, null, null);
if(member)
{
- type = eSystem_FindClass(__thisModule, member.dataTypeString);
- if(!type)
- type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
-
+ type = superFindClass(member.dataTypeString, objectType.module);
offset = member._class.offset + member.offset;
}
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);
- }
+ type = superFindClass(prop.dataTypeString, objectType.module);
else
PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
}
}
}
+ if(type && type.templateClass && type.templateClass == class(Container))
+ {
+ char * br = strchr(type.fullName, '<');
+ if(br)
+ {
+ char className[1024];
+ strcpy(className, "Array");
+ strcat(className, br);
+ type = superFindClass(className, objectType.module);
+ }
+ }
+
// Find Member in Object Class
{
DataValue value { };
if(type && type.type == structClass)
{
- value.p = (byte *)*object + offset;
+ if(member)
+ {
+ value.p = (byte *)*object + offset;
+ memset(value.p, 0, type.structSize);
+ }
+ else if(prop)
+ {
+ value.p = new0 byte[type.structSize];
+ }
+ }
+ if(!eCON)
+ {
+ ch = 0;
+ SkipEmpty();
}
- ch = 0;
- SkipEmpty();
- if(ch == ':')
+ if(eCON && ch != '=' && ch != ':')
+ {
+ f.Seek(seek-1, start);
+ ch = 0;
+ }
+ if((ch == ':' || (eCON && ch == '=')) || (eCON && type && (prop || member)))
{
JSONResult itemResult = GetValue(type, value);
if(itemResult != syntaxError)
if(prop || member)
{
if(!type)
- {
PrintLn("warning: Unresolved data type ", member ? (String)member.dataTypeString : (String)prop.dataTypeString);
- }
else if(itemResult == success)
{
+ BitMember bitMember = objectType.type == bitClass ? (BitMember) member : null;
// Set value
if(member)
{
}
else if(type == class(double) || !strcmp(type.dataTypeString, "double"))
{
- *(double *)((byte *)*object + offset) = value.d;
+ if(objectType.type != bitClass)
+ {
+ *(double *)((byte *)*object + offset) = value.d;
+ }
}
else if(type == class(float) || !strcmp(type.dataTypeString, "float"))
{
- *(float *)((byte *)*object + offset) = value.f;
+ if(objectType.type != bitClass)
+ {
+ *(float *)((byte *)*object + offset) = value.f;
+ }
}
else if(type.typeSize == sizeof(int64) || !strcmp(type.dataTypeString, "int64") ||
!strcmp(type.dataTypeString, "unsigned int64") || !strcmp(type.dataTypeString, "uint64"))
{
- *(uint64 *)((byte *)*object + offset) = value.ui64;
+ if(objectType.type == bitClass)
+ {
+ bits &= ~bitMember.mask;
+ bits |= (value.ui64 << bitMember.pos) & bitMember.mask;
+ }
+ else
+ {
+ *(uint64 *)((byte *)*object + offset) = value.ui64;
+ }
}
else if(type.typeSize == sizeof(int) || !strcmp(type.dataTypeString, "int") ||
!strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
{
- *(int *)((byte *)*object + offset) = value.i;
+ if(objectType.type == bitClass)
+ {
+ bits &= ~bitMember.mask;
+ bits |= (value.ui << bitMember.pos) & bitMember.mask;
+ }
+ else
+ {
+ *(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") ||
!strcmp(type.dataTypeString, "int16"))
{
- *(short *)((byte *)*object + offset) = value.s;
+ if(objectType.type == bitClass)
+ {
+ bits &= ~bitMember.mask;
+ bits |= (value.us << bitMember.pos) & bitMember.mask;
+ }
+ else
+ {
+ *(short *)((byte *)*object + offset) = value.s;
+ }
}
else if(type.typeSize == sizeof(byte) || !strcmp(type.dataTypeString, "char") ||
!strcmp(type.dataTypeString, "unsigned char") || !strcmp(type.dataTypeString, "byte"))
{
- *(char *)((byte *)*object + offset) = value.c;
+ if(objectType.type == bitClass)
+ {
+ bits &= ~bitMember.mask;
+ bits |= (value.uc << bitMember.pos) & bitMember.mask;
+ }
+ else
+ {
+ *(char *)((byte *)*object + offset) = value.c;
+ }
}
else
{
- *(void **)((byte *)*object + offset) = value.p;
+ if(objectType.type != bitClass)
+ *(void **)((byte *)*object + offset) = value.p;
}
}
else if(prop && prop.Set)
{
- if(!strcmp(type.dataTypeString, "char *"))
+ if(objectType.type == bitClass)
+ {
+ if(type.type == enumClass || type.type == bitClass || type.type == unitClass || type.type == systemClass)
+ {
+ switch(objectType.typeSize)
+ {
+ case 1:
+ switch(type.typeSize)
+ {
+ case 1: ((byte (*)(byte, byte)) (void *)prop.Set)((byte)bits, value.uc); break;
+ case 2: ((byte (*)(byte, uint16))(void *)prop.Set)((byte)bits, value.us); break;
+ case 4: ((byte (*)(byte, uint32))(void *)prop.Set)((byte)bits, value.ui); break;
+ case 8: ((byte (*)(byte, uint64))(void *)prop.Set)((byte)bits, value.ui64); break;
+ }
+ break;
+ case 2:
+ switch(type.typeSize)
+ {
+ case 1: ((uint16 (*)(uint16, byte)) (void *)prop.Set)((uint16)bits, value.uc); break;
+ case 2: ((uint16 (*)(uint16, uint16))(void *)prop.Set)((uint16)bits, value.us); break;
+ case 4: ((uint16 (*)(uint16, uint32))(void *)prop.Set)((uint16)bits, value.ui); break;
+ case 8: ((uint16 (*)(uint16, uint64))(void *)prop.Set)((uint16)bits, value.ui64); break;
+ }
+ break;
+ case 4:
+ switch(type.typeSize)
+ {
+ case 1: ((uint32 (*)(uint32, byte)) (void *)prop.Set)((uint32)bits, value.uc); break;
+ case 2: ((uint32 (*)(uint32, uint16))(void *)prop.Set)((uint32)bits, value.us); break;
+ case 4: ((uint32 (*)(uint32, uint32))(void *)prop.Set)((uint32)bits, value.ui); break;
+ case 8: ((uint32 (*)(uint32, uint64))(void *)prop.Set)((uint32)bits, value.ui64); break;
+ }
+ break;
+ case 8:
+ switch(type.typeSize)
+ {
+ case 1: ((uint64 (*)(uint64, byte)) (void *)prop.Set)((uint64)bits, value.uc); break;
+ case 2: ((uint64 (*)(uint64, uint16))(void *)prop.Set)((uint64)bits, value.us); break;
+ case 4: ((uint64 (*)(uint64, uint32))(void *)prop.Set)((uint64)bits, value.ui); break;
+ case 8: ((uint64 (*)(uint64, uint64))(void *)prop.Set)((uint64)bits, value.ui64); break;
+ }
+ break;
+ }
+ }
+ else
+ ; // TODO: Generate error
+ }
+ else if(!strcmp(type.dataTypeString, "char *"))
{
((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
if(!isKey)
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);
- }
- 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
{
- ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
+ if(isTemplateArg)
+ ((void (*)(void *, uint64))(void *)prop.Set)(*object, (uint64)(uintptr)value.p);
+ else
+ ((void (*)(void *, void *))(void *)prop.Set)(*object, value.p);
}
}
}
}
else
result = syntaxError;
+
+ if(prop && type && type.type == structClass)
+ {
+ delete value.p;
+ }
}
}
- else if(ch && ch != '}' && ch != ',')
+ else if(ch && ch != '}' && ch != ',' && (!eCON || ch != ';'))
result = syntaxError;
delete string;
{
break;
}
- else if(ch != ',')
+ else if(ch != ',' && (!eCON || ch != ';'))
result = syntaxError;
}
}
+
+ if(objectType.type == bitClass)
+ {
+ switch(objectType.typeSize)
+ {
+ case 1: *(uint64 *)object = (byte) bits; break;
+ case 2: *(uint64 *)object = (uint16) bits; break;
+ case 4: *(uint64 *)object = (uint32) bits; break;
+ case 8: *(uint64 *)object = (uint64) bits; break;
+ }
+ }
}
ch = 0;
return result;
JSONResult GetNumber(Class type, DataValue value)
{
- JSONResult result = syntaxError;
+ JSONResult result = success;
char buffer[256];
int c = 0;
- while(c < sizeof(buffer)-1 && (ch == '-' || ch == '.' || tolower(ch) == 'e' || ch == '+' || isdigit(ch)))
+ bool comment = false;
+ bool hexMode = false;
+ if(eCON)
{
- buffer[c++] = ch;
- if(!f.Getc(&ch)) break;
+ while(c < sizeof(buffer)-1 && (comment || ch == '-' || ch == '.' || tolower(ch) == 'f' ||
+ (c == 1 && tolower(ch) == 'x' && buffer[0] == '0') || tolower(ch) == 'e' || ch == '+' || isdigit(ch) || ch == '/' ||
+ (hexMode && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))))
+ {
+ if(!comment && ch == '/')
+ {
+ if(f.Getc(&ch))
+ {
+ if(ch == '*')
+ comment = true;
+ }
+ else
+ {
+ result = syntaxError;
+ break;
+ }
+ }
+ else if(comment && ch == '*')
+ {
+ if(f.Getc(&ch))
+ {
+ if(ch == '/')
+ comment = false;
+ }
+ else
+ {
+ result = syntaxError;
+ break;
+ }
+ }
+ else if(!comment)
+ {
+ if(c == 1 && ch == 'x' && buffer[0] == '0')
+ hexMode = true;
+ buffer[c++] = ch;
+ }
+ if(!f.Getc(&ch)) break;
+ }
+ }
+ else
+ {
+ while(c < sizeof(buffer)-1 && (ch == '-' || ch == '.' || tolower(ch) == 'e' || ch == '+' || isdigit(ch)))
+ {
+ buffer[c++] = ch;
+ if(!f.Getc(&ch)) break;
+ }
}
buffer[c] = 0;
//if(strchr(buffer, '.'))
+ if(result == syntaxError)
+ return result;
+ if(!type) return success;
+ result = syntaxError;
// TOFIX: How to swiftly handle classes with base data type?
if(type == class(double) || !strcmp(type.dataTypeString, "double"))
//else if(type == class(int64) || !strcmp(type.dataTypeString, "int64"))
else if(!strcmp(type.dataTypeString, "int64"))
{
- value.i64 = strtol(buffer, null, 10); // TOFIX: 64 bit support
+ value.i64 = strtol(buffer, null, eCON ? 0 : 10); // TOFIX: 64 bit support
result = success;
}
else if(type == class(uint64) || !strcmp(type.dataTypeString, "uint64"))
{
- value.ui64 = strtol(buffer, null, 10); // TOFIX: 64 bit support
+ value.ui64 = strtoul(buffer, null, eCON ? 0 : 10); // TOFIX: 64 bit support
+ result = success;
+ }
+ else if(type == class(uint) || !strcmp(type.dataTypeString, "unsigned int") || !strcmp(type.dataTypeString, "uint"))
+ {
+ value.ui = (uint)strtoul(buffer, null, eCON ? 0 : 10); // TOFIX: 64 bit support
result = success;
}
else
{
- value.i = strtol(buffer, null, 10);
+ value.i = (int)strtol(buffer, null, eCON ? 0 : 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;
+ if(!strcmp(prop.name, type.base.fullName))
+ refProp = true;
+ else
+ {
+ Class c = eSystem_FindClass(type.module, prop.name);
+ if(!c)
+ c = eSystem_FindClass(type.module.application, prop.name);
+ if(c)
+ {
+ 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;
}
+
+ JSONResult GetColorAlpha(String string, DataValue value)
+ {
+ ColorAlpha color = 0;
+ DefinedColor c = 0;
+ if(string)
+ {
+ if(string[0] == '0' && string[1] == 'x')
+ color = (uint)strtoul(string, null, 0);
+ else
+ {
+ char *d;
+ byte a = 255;
+ if((d = strchr(string, ',')))
+ {
+ a = (byte)atoi(string);
+ d += 2;
+ }
+ else
+ d = string;
+ if(c.class::OnGetDataFromString(d))
+ {
+ color.a = a;
+ color.color = c;
+ }
+ else
+ color = (uint)strtoul(string, null, 16);
+ }
+ }
+ value.i = color;
+ return success;
+ }
}
-bool WriteMap(File f, Class type, Map map, int indent)
+static bool WriteMap(File f, Class type, Map map, int indent, bool eCON)
{
if(map)
{
else
isFirst = false;
for(i = 0; i<indent; i++) f.Puts(" ");
- _WriteJSONObject(f, mapNodeClass, n, indent);
+ WriteONObject(f, mapNodeClass, n, indent, eCON, eCON ? true : false);
}
f.Puts("\n");
indent--;
return true;
}
-bool WriteArray(File f, Class type, Container array, int indent)
+static bool WriteArray(File f, Class type, Container array, int indent, bool eCON)
{
if(array)
{
value.p = (void *)(uintptr)t;
}
for(i = 0; i<indent; i++) f.Puts(" ");
- WriteValue(f, arrayType, value, indent);
+ WriteValue(f, arrayType, value, indent, eCON);
}
f.Puts("\n");
indent--;
return true;
}
-bool WriteNumber(File f, Class type, DataValue value, int indent)
+static bool WriteNumber(File f, Class type, DataValue value, int indent, bool eCON, bool useHex)
{
char buffer[1024];
- bool needClass = false;
+ bool needClass = eCON;
+ bool quote;
buffer[0] = 0;
if(type == class(double) || !strcmp(type.dataTypeString, "double"))
((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.d, buffer, 0, &needClass);
else if(!strcmp(type.dataTypeString, "int64"))
((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))
- ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui64, buffer, null, &needClass);
+ {
+ if(useHex && eCON)
+ sprintf(buffer, __runtimePlatform == win32 ? "0x%016I64X" : "0x%016llX", value.ui64);
+ else
+ ((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"))
((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))
- ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &value.ui, buffer, null, &needClass);
+ {
+ if(useHex && eCON)
+ sprintf(buffer, "0x%08X", value.ui);
+ else
+ ((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"))
((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))
((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))
((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, ' '))) ||
+ (type.type == enumClass && !eCON);
+ if(quote) f.Puts("\"");
f.Puts(buffer);
+ if(quote) f.Puts("\"");
return true;
}
-bool WriteValue(File f, Class type, DataValue value, int indent)
+public bool WriteColorAlpha(File f, Class type, DataValue value, int indent, bool eCON)
+{
+ char buffer[1024];
+ char * string = buffer;
+ ColorAlpha color = value.i;
+ int a = color.a;
+ int len;
+ DefinedColor c = color;
+ buffer[0] = '\0';
+ if(a != 255)
+ {
+ a.class::OnGetString(buffer, null, null);
+ len = strlen(buffer);
+ buffer[len++] = ',';
+ buffer[len++] = ' ';
+ buffer[len] = '\0';
+ string += len;
+ }
+ if(!c.class::OnGetString(string, null, null))
+ sprintf(buffer, "0x%x", color);
+ if(!eCON)
+ f.Puts("\"");
+ f.Puts(buffer);
+ if(!eCON)
+ f.Puts("\"");
+ return true;
+}
+
+static bool WriteValue(File f, Class type, DataValue value, int indent, bool eCON)
{
if(!strcmp(type.name, "String") || !strcmp(type.dataTypeString, "char *"))
{
{
f.Puts("\"");
//if(strchr(value.p, '\"') || strchr(value.p, '\\'))
+ if(eCON)
+ {
+ int c = 0;
+ int b = 0;
+ char buffer[1024];
+ char * string = value.p;
+ char ch;
+ while(true)
+ {
+ 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(ch == '\t')
+ {
+ buffer[b] = 0;
+ f.Puts(buffer);
+ f.Puts("\\t");
+ b = 0;
+ }
+ else if(c >= 4 && ch == '>' && string[c-2] == 'r' && string[c-3] == 'b' && string[c-4] == '<')
+ {
+ // Add an automatic newline for <br> as this is how we imported documentor data...
+ int i;
+ buffer[b] = 0;
+ f.Puts(buffer);
+ f.Puts(">\"\n");
+ for(i = 0; i<indent; i++) f.Puts(" ");
+ f.Puts(" \"");
+ b = 0;
+ }
+ else if(ch == '\n')
+ {
+ int i;
+ buffer[b] = 0;
+ f.Puts(buffer);
+ f.Puts("\\n\"\n");
+ for(i = 0; i<indent; i++) f.Puts(" ");
+ 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
{
int c = 0;
int b = 0;
else
f.Puts("unset");
}
- else if(type.type == enumClass || type.type == unitClass)
- {
- f.Puts("\"");
- WriteNumber(f, type, value, indent);
- f.Puts("\"");
- }
+ else if(type.type == enumClass)
+ WriteNumber(f, type, value, indent, eCON, false);
else if(eClass_IsDerived(type, class(Map)))
{
- WriteMap(f, type, value.p, indent);
+ WriteMap(f, type, value.p, indent, eCON);
}
else if(eClass_IsDerived(type, class(Container)))
{
- WriteArray(f, type, value.p, indent);
+ WriteArray(f, type, value.p, indent, eCON);
}
else if(type.type == normalClass || type.type == noHeadClass || type.type == structClass)
{
- _WriteJSONObject(f, type, value.p, indent);
+ WriteONObject(f, type, value.p, indent, eCON, false);
+ }
+ else if(eClass_IsDerived(type, class(ColorAlpha)))
+ {
+ WriteColorAlpha(f, type, value, indent, eCON);
}
else if(type.type == bitClass)
{
Class dataType;
- dataType = eSystem_FindClass(__thisModule, type.dataTypeString);
- WriteNumber(f, dataType, value, indent);
+ dataType = superFindClass(type.dataTypeString, type.module);
+ WriteNumber(f, dataType, value, indent, eCON, true);
}
- else if(type.type == systemClass)
+ else if(type.type == systemClass || type.type == unitClass)
{
- WriteNumber(f, type, value, indent);
+ WriteNumber(f, type, value, indent, eCON, false);
}
return true;
}
bool result = false;
if(object)
{
- result = _WriteJSONObject(f, objectType, object, indent);
+ result = WriteONObject(f, objectType, object, indent, false, false);
f.Puts("\n");
}
return result;
}
-static bool _WriteJSONObject(File f, Class objectType, void * object, int indent)
+public bool WriteECONObject(File f, Class objectType, void * object, int indent)
+{
+ bool result = false;
+ if(object)
+ {
+ result = WriteONObject(f, objectType, object, indent, true, false);
+ f.Puts("\n");
+ }
+ return result;
+}
+
+static bool WriteONObject(File f, Class objectType, void * object, int indent, bool eCON, bool omitDefaultIdentifier)
{
if(object)
{
}
else
{
+ Class _class = (eCON && objectType.type == normalClass) ? ((Instance)object)._class : objectType;
Property prop;
int c;
bool isFirst = true;
mapDataClass = objectType.templateArgs[2].dataTypeClass;
}
+ if(eCON && _class != objectType && eClass_IsDerived(_class, objectType))
+ {
+ f.Puts(_class.name);
+ f.Puts(" ");
+ }
+
f.Puts("{\n");
indent++;
- for(baseClass = objectType; baseClass; baseClass = baseClass.base)
+ for(baseClass = _class; baseClass; baseClass = baseClass.base)
{
if(baseClass.isInstanceClass || !baseClass.base)
break;
if(!prop.conversion && (!prop.IsSet || prop.IsSet(object)))
{
DataValue value { };
+ bool isTemplateArg = false;
Class type;
if(mapKeyClass && !strcmp(prop.name, "key"))
+ {
+ isTemplateArg = true;
type = mapKeyClass;
+ }
else if(mapDataClass && !strcmp(prop.name, "value"))
+ {
+ isTemplateArg = true;
type = mapDataClass;
+ }
else
- type = eSystem_FindClass(__thisModule, prop.dataTypeString);
- if(!type)
- type = eSystem_FindClass(__thisModule.application, prop.dataTypeString);
+ type = superFindClass(prop.dataTypeString, _class.module);
+
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"))
+ if(type.type == enumClass || type.type == bitClass || type.type == unitClass || type.type == systemClass)
{
- 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);
+ // 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 = new byte[type.structSize];
+ value.p = new0 byte[type.structSize];
((void (*)(void *, void *))(void *)prop.Get)(object, value.p);
}
else
{
- value.p = ((void *(*)(void *))(void *)prop.Get)(object);
+ if(isTemplateArg)
+ value.p = (void *)(uintptr)((uint64 (*)(void *))(void *)prop.Get)(object);
+ else
+ value.p = ((void *(*)(void *))(void *)prop.Get)(object);
}
if(!isFirst) f.Puts(",\n");
for(c = 0; c<indent; c++) f.Puts(" ");
- f.Puts("\"");
- f.Putc((char)toupper(prop.name[0]));
- f.Puts(prop.name+1);
- f.Puts("\" : ");
- WriteValue(f, type, value, indent);
+ if(!eCON)
+ {
+ f.Puts("\"");
+ f.Putc((char)toupper(prop.name[0]));
+ f.Puts(prop.name+1);
+ f.Puts("\" : ");
+ }
+ else if(!omitDefaultIdentifier)
+ {
+ f.Puts(prop.name);
+ f.Puts(" = ");
+ }
+ WriteValue(f, type, value, indent, eCON);
isFirst = false;
if(type.type == structClass)
delete value.p;
DataMember member = (DataMember)prop;
DataValue value { };
uint offset;
- Class type = eSystem_FindClass(__thisModule, member.dataTypeString);
- if(!type)
- type = eSystem_FindClass(__thisModule.application, member.dataTypeString);
-
+ Class type = superFindClass(member.dataTypeString, _class.module);
offset = member._class.offset + member.offset;
if(type)
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);
+ if(!eCON)
+ {
+ f.Puts("\"");
+ f.Putc((char)toupper(member.name[0]));
+ f.Puts(member.name+1);
+ f.Puts("\" : ");
+ }
+ else if(!omitDefaultIdentifier)
+ {
+ f.Puts(member.name);
+ f.Puts(" = ");
+ }
+ WriteValue(f, type, value, indent, eCON);
isFirst = false;
}
}
f.Puts("null");
return true;
}
+
+static Class superFindClass(const String name, Module alternativeModule)
+{
+ Class _class = eSystem_FindClass(__thisModule, name);
+ if(!_class && alternativeModule)
+ _class = eSystem_FindClass(alternativeModule, name);
+ if(!_class)
+ _class = eSystem_FindClass(__thisModule.application, name);
+ return _class;
+}
+
+static bool isSubclass(Class type, const String name)
+{
+ Class _class = superFindClass(name, type.module);
+ if(eClass_IsDerived(_class, type))
+ return true;
+ return false;
+}