Changeset 753 for cpp/frams


Ignore:
Timestamp:
03/02/18 18:43:49 (2 years ago)
Author:
Maciej Komosinski
Message:

Improved Vector and Dictionary deserialization: any number of spaces allowed in empty object, special error message for missing ']' or '}', comma after the last element is no longer allowed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpp/frams/util/extvalue.cpp

    r698 r753  
    11// This file is a part of Framsticks SDK.  http://www.framsticks.com/
    2 // Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
     2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
    33// See LICENSE.txt for details.
    44
     
    748748SString ExtValue::formatTime(char fmt, double value)
    749749{
    750 if (fmt=='i')
     750        if (fmt == 'i')
    751751        { //could be Convert::ctime()
    752         int d,h,m,ti=value;
    753         int ms=1000*(value-ti);
    754         d=ti/86400; ti-=d*86400;
    755         h=ti/3600; ti-=h*3600;
    756         m=ti/60; ti-=m*60;
    757         SString ret;
    758         if (d>0) ret+=SString::sprintf("%dd ",d);
    759         if (h>0) ret+=SString::sprintf("%d:",h);
    760         ret+=SString::sprintf("%02d:%02d.%03d", m,ti,ms);
    761         return ret;
    762         }
    763 time_t ti = value;
    764 struct tm tm = Convert::localtime(ti);
    765 switch(fmt)
     752                int d, h, m, ti = value;
     753                int ms = 1000 * (value - ti);
     754                d = ti / 86400; ti -= d * 86400;
     755                h = ti / 3600; ti -= h * 3600;
     756                m = ti / 60; ti -= m * 60;
     757                SString ret;
     758                if (d > 0) ret += SString::sprintf("%dd ", d);
     759                if (h > 0) ret += SString::sprintf("%d:", h);
     760                ret += SString::sprintf("%02d:%02d.%03d", m, ti, ms);
     761                return ret;
     762        }
     763        time_t ti = value;
     764        struct tm tm = Convert::localtime(ti);
     765        switch (fmt)
    766766        {
    767767        case 'T': return SString::sprintf("%04d-%02d-%02d %02d:%02d:%02d", 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
    768768        case 't': return SString(Convert::asctime(tm).c_str());
    769769        case 'y': return SString::sprintf("%04d-%02d-%02d", 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday);
    770         case 'm': return SString::sprintf("%04d-%02d-%02d %02d:%02d:%02d.%03d", 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, int(1000*(value-(double)ti)));
    771         }
    772 return SString();
     770        case 'm': return SString::sprintf("%04d-%02d-%02d %02d:%02d:%02d.%03d", 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, int(1000 * (value - (double)ti)));
     771        }
     772        return SString();
    773773}
    774774
     
    834834                case 't': case 'T': case 'i': case 'y': case 'm':
    835835                        a = args.getNext();
    836                         ret += formatTime(type,a ? a->getDouble() : 0);
     836                        ret += formatTime(type, a ? a->getDouble() : 0);
    837837                        ret += sub.substr(2);
    838838                        break;
     
    865865        }
    866866        else
    867                 setDouble(fmod(ddata(),a));
     867                setDouble(fmod(ddata(), a));
    868868}
    869869
     
    11121112                tlsGetRef(ExtObject_serialization).add(o);
    11131113                const char* p = in + 1;
    1114                 ExtValue tmp;
    1115                 while (*p)
    1116                 {
    1117                         if (isspace(*p)) p++;
    1118                         if (*p == ']') { p++; break; }
     1114                ExtValue tmp; bool first = true, comma = false;
     1115                const char* prev_element = p;
     1116                while (true)
     1117                {
     1118                        while (isspace(*p)) p++;
     1119                        if (*p == 0)
     1120                        {
     1121                                logPrintf("ExtValue", "deserialize", LOG_ERROR, "Missing ']' in Vector");
     1122                                return NULL;
     1123                        }
     1124                        if (*p == ']')
     1125                        {
     1126                                if (comma)
     1127                                {
     1128                                        logPrintf("ExtValue", "deserialize", LOG_ERROR, "No element after ',' in Vector");
     1129                                        return NULL;
     1130                                }
     1131                                p++;
     1132                                break;
     1133                        }
     1134                        if (!first && !comma)
     1135                        {
     1136                                logPrintf("ExtValue", "deserialize", LOG_ERROR, "Missing ',' in Vector: '%s'", prev_element);
     1137                                return NULL;
     1138                        }
    11191139                        ret = tmp.deserialize(p);
     1140                        prev_element = p; first = false; comma = false;
    11201141                        if (ret)
    11211142                        {
    11221143                                vec->data += new ExtValue(tmp);
    11231144                                p = ret;
    1124                                 if (*p == ',') p++;
    1125                                 else if (*p != ']')
    1126                                 {
    1127                                         logPrintf("ExtValue", "deserialize", LOG_ERROR, "Missing ',' in Vector: '%s'", p);
    1128                                         return NULL;
    1129                                 }
     1145                                if (*p == ',') { p++; comma = true; }
    11301146                        }
    11311147                        else
     
    11451161                const char* p = in + 1;
    11461162                ExtValue args[2]/*={value,key}*/, dummy_ret;
    1147                 while (*p)
    1148                 {
    1149                         if (isspace(*p)) p++;
    1150                         if (*p == '}') { p++; break; }
     1163                bool first = true, comma = false;
     1164                const char* prev_element = p;
     1165                while (true)
     1166                {
     1167                        while (isspace(*p)) p++;
     1168                        if (*p == 0)
     1169                        {
     1170                                logPrintf("ExtValue", "deserialize", LOG_ERROR, "Missing '}' in Dictionary");
     1171                                return NULL;
     1172                        }
     1173                        if (*p == '}')
     1174                        {
     1175                                if (comma)
     1176                                {
     1177                                        logPrintf("ExtValue", "deserialize", LOG_ERROR, "No element after ',' in Dictionary");
     1178                                        return NULL;
     1179                                }
     1180                                p++;
     1181                                break;
     1182                        }
     1183                        if (!first && !comma)
     1184                        {
     1185                                logPrintf("ExtValue", "deserialize", LOG_ERROR, "Missing ',' in Dictionary: '%s'", prev_element);
     1186                                return NULL;
     1187                        }
    11511188                        ret = args[1].deserialize(p);
     1189                        prev_element = p; first = false; comma = false;
    11521190                        if ((!ret) || (args[1].getType() != TString)) { p = NULL; break; }
    11531191                        p = ret;
     
    11581196                        p = ret;
    11591197                        dic->p_set(args, &dummy_ret);
    1160                         if (*p == ',') p++;
    1161                         else if (*p != '}')
    1162                         {
    1163                                 logPrintf("ExtValue", "deserialize", LOG_ERROR, "Missing ',' in Dictionary: '%s'", p);
    1164                                 return NULL;
    1165                         }
     1198                        if (*p == ',') { p++; comma = true; }
    11661199                }
    11671200                setObject(o);
Note: See TracChangeset for help on using the changeset viewer.