ecere/sys/ECON: Fixed ECON Hexadecimal Support; Using it for bit classes
[sdk] / ecere / src / sys / JSON.ec
index 4e9052b..a813a81 100644 (file)
@@ -31,11 +31,16 @@ public enum SetBool : uint
 };
 
 
+public class ECONParser : JSONParser
+{
+   eCON = true;
+}
+
 public class JSONParser
 {
 public:
    File f;
-   char pch;
+private:
    char ch;
    bool eCON;
 
@@ -177,7 +182,7 @@ public:
             }
          }
       }
-      else if(isalpha(ch))
+      else if(isalpha(ch) || ch == '_')
       {
          if(eCON)
          {
@@ -185,7 +190,7 @@ public:
             if(GetIdentifier(&string, null))
             {
                result = success;
-               if(eCON && (type.type == enumClass || type.type == unitClass))
+               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))
@@ -212,10 +217,10 @@ public:
                   if(type.type != structClass)
                      value.p = 0;
                }
-               else if(isSubclass(string, type))
+               else if(isSubclass(type, string))
                {
                   void * object = value.p;
-                  Class subtype = eSystem_SuperFindClass(string, type.module);
+                  Class subtype = superFindClass(string, type.module);
                   SkipEmpty();
                   result = GetObject(subtype, &object);
                   if(result)
@@ -242,7 +247,7 @@ public:
          {
             char buffer[256];
             int c = 0;
-            while(c < sizeof(buffer)-1 && isalpha(ch))
+            while(c < sizeof(buffer)-1 && (isalpha(ch) || isdigit(ch) || ch == '_'))
             {
                buffer[c++] = ch;
                if(!f.Getc(&ch)) break;
@@ -502,7 +507,7 @@ public:
                break;
             }
          }
-         else if(ch == '\"' || (!comment && ch && !isalpha(ch)))
+         else if(ch == '\"' || (!quoted && !comment && ch && !isalpha(ch) && !isdigit(ch) && ch != '_'))
          {
             if(quoted && ch == '\"' && wasQuoted)
                *wasQuoted = true;
@@ -521,7 +526,7 @@ public:
          *string = CopyString(buffer.array);
       }
       delete buffer;
-      if(ch != ',' && ch != '}' && ch != ';' && ch != '/' && ch != '=')
+      if(ch != ',' && ch != '}' && ch != ';' && ch != '/' && ch != '=' && ch != ':')
          ch = 0;
       return result;
    }
@@ -582,7 +587,7 @@ public:
                         lineComment = false;
                      else if(comment && pch == '*' && ch == '/')
                         comment = false;
-                     else if(ch == '=' || ch == ';' || ch == ',' || ch == '}')
+                     else if(ch == '=' || ch == ':' || ch == ';' || ch == ',' || ch == ']' || ch == '}')
                      {
                         ch = 0;
                         seekback = -1;
@@ -679,8 +684,10 @@ public:
                {
                   SkipEmpty();
                   prop = null; member = null;
-                  if(ch == '=')
+                  if(ch == '=' || ch == ':')
                   {
+                     if(wasQuoted)
+                        string[0] = (char)tolower(string[0]);
                      while(1)
                      {
                         eClass_FindNextMember(objectType, &curClass, &curMember, subMemberStack, &subMemberStackPos);
@@ -710,16 +717,16 @@ public:
                            offset = member._class.offset + member.offset;
                      }
                      else if(prop)
-                        type = eSystem_SuperFindClass(prop.dataTypeString, objectType.module);
+                        type = superFindClass(prop.dataTypeString, objectType.module);
                      else if(member)
                      {
-                        type = eSystem_SuperFindClass(member.dataTypeString, objectType.module);
+                        type = superFindClass(member.dataTypeString, objectType.module);
                         offset = member._class.offset + member.offset;
                      }
                   }
                   else
                   {
-                     if(ch == '=')
+                     if(ch == '=' || ch == ':')
                         PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
                      else
                         PrintLn("Warning: default member assignment: no more members");
@@ -746,14 +753,14 @@ public:
                      member = eClass_FindDataMember(objectType, string, objectType.module, null, null);
                      if(member)
                      {
-                        type = eSystem_SuperFindClass(member.dataTypeString, objectType.module);
+                        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_SuperFindClass(prop.dataTypeString, objectType.module);
+                           type = superFindClass(prop.dataTypeString, objectType.module);
                         else
                            PrintLn("Warning: member ", string, " not found in class ", (String)objectType.name);
                      }
@@ -780,12 +787,12 @@ public:
                      ch = 0;
                      SkipEmpty();
                   }
-                  if(eCON && ch != '=')
+                  if(eCON && ch != '=' && ch != ':')
                   {
                      f.Seek(seek-1, start);
                      ch = 0;
                   }
-                  if(ch == (eCON ? '=' : ':') || (eCON && type && (prop || member)))
+                  if((ch == ':' || (eCON && ch == '=')) || (eCON && type && (prop || member)))
                   {
                      JSONResult itemResult = GetValue(type, value);
                      if(itemResult != syntaxError)
@@ -944,10 +951,12 @@ public:
       char buffer[256];
       int c = 0;
       bool comment = false;
+      bool hexMode = false;
       if(eCON)
       {
          while(c < sizeof(buffer)-1 && (comment || ch == '-' || ch == '.' || tolower(ch) == 'f' ||
-                     tolower(ch) == 'x' || tolower(ch) == 'e' || ch == '+' || isdigit(ch) || ch == '/'))
+                     (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 == '/')
             {
@@ -976,7 +985,11 @@ public:
                }
             }
             else if(!comment)
+            {
+               if(c == 1 && ch == 'x' && buffer[0] == '0')
+                  hexMode = true;
                buffer[c++] = ch;
+            }
             if(!f.Getc(&ch)) break;
          }
       }
@@ -1018,7 +1031,7 @@ public:
          value.ui64 = strtoul(buffer, null, eCON ? 0 : 10);  // TOFIX: 64 bit support
          result = success;
       }
-      else if(type == class(uint) || !strcmp(type.dataTypeString, "unsigned int"))
+      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;
@@ -1220,7 +1233,7 @@ static bool WriteArray(File f, Class type, Container array, int indent, bool eCO
    return true;
 }
 
-static bool WriteNumber(File f, Class type, DataValue value, int indent, bool eCON)
+static bool WriteNumber(File f, Class type, DataValue value, int indent, bool eCON, bool useHex)
 {
    char buffer[1024];
    bool needClass = eCON;
@@ -1233,11 +1246,21 @@ static bool WriteNumber(File f, Class type, DataValue value, int indent, bool eC
    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)
+         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)
+         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))
@@ -1247,7 +1270,8 @@ static bool WriteNumber(File f, Class type, DataValue value, int indent, bool eC
    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, ' ')));
+   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("\"");
@@ -1403,13 +1427,7 @@ static bool WriteValue(File f, Class type, DataValue value, int indent, bool eCO
          f.Puts("unset");
    }
    else if(type.type == enumClass)
-   {
-      if(!eCON)
-         f.Puts("\"");
-      WriteNumber(f, type, value, indent, eCON);
-      if(!eCON)
-         f.Puts("\"");
-   }
+      WriteNumber(f, type, value, indent, eCON, false);
    else if(eClass_IsDerived(type, class(Map)))
    {
       WriteMap(f, type, value.p, indent, eCON);
@@ -1429,12 +1447,12 @@ static bool WriteValue(File f, Class type, DataValue value, int indent, bool eCO
    else if(type.type == bitClass)
    {
       Class dataType;
-      dataType = eSystem_SuperFindClass(type.dataTypeString, type.module);
-      WriteNumber(f, dataType, value, indent, eCON);
+      dataType = superFindClass(type.dataTypeString, type.module);
+      WriteNumber(f, dataType, value, indent, eCON, true);
    }
    else if(type.type == systemClass || type.type == unitClass)
    {
-      WriteNumber(f, type, value, indent, eCON);
+      WriteNumber(f, type, value, indent, eCON, false);
    }
    return true;
 }
@@ -1541,7 +1559,7 @@ static bool WriteONObject(File f, Class objectType, void * object, int indent, b
                         type = mapDataClass;
                      }
                      else
-                        type = eSystem_SuperFindClass(prop.dataTypeString, _class.module);
+                        type = superFindClass(prop.dataTypeString, _class.module);
 
                      if(!type)
                         PrintLn("warning: Unresolved data type ", (String)prop.dataTypeString);
@@ -1620,7 +1638,7 @@ static bool WriteONObject(File f, Class objectType, void * object, int indent, b
                   DataMember member = (DataMember)prop;
                   DataValue value { };
                   uint offset;
-                  Class type = eSystem_SuperFindClass(member.dataTypeString, _class.module);
+                  Class type = superFindClass(member.dataTypeString, _class.module);
                   offset = member._class.offset + member.offset;
 
                   if(type)
@@ -1705,7 +1723,7 @@ static bool WriteONObject(File f, Class objectType, void * object, int indent, b
    return true;
 }
 
-static Class eSystem_SuperFindClass(const String name, Module alternativeModule)
+static Class superFindClass(const String name, Module alternativeModule)
 {
    Class _class = eSystem_FindClass(__thisModule, name);
    if(!_class && alternativeModule)
@@ -1715,9 +1733,9 @@ static Class eSystem_SuperFindClass(const String name, Module alternativeModule)
    return _class;
 }
 
-static bool isSubclass(const String name, Class type)
+static bool isSubclass(Class type, const String name)
 {
-   Class _class = eSystem_SuperFindClass(name, type.module);
+   Class _class = superFindClass(name, type.module);
    if(eClass_IsDerived(_class, type))
       return true;
    return false;