//----------------------------------------------------------------------------- // Loads and parses the given JSON file pathname and returns a JSON object tree. // The returned object must be Released after use. JSON* JSON::Load(const char* path, const char** perror) { SysFile f; if (!f.Open(path, File::Open_Read, File::Mode_Read)) { AssignError(perror, "Failed to open file"); return NULL; } int len = f.GetLength(); uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1); int bytes = f.Read(buff, len); f.Close(); if (bytes == 0 || bytes != len) { OVR_FREE(buff); return NULL; } // Ensure the result is null-terminated since Parse() expects null-terminated input. buff[len] = '\0'; JSON* json = JSON::Parse((char*)buff, perror); OVR_FREE(buff); return json; }
void TPersistent::Assign(const TPersistent * Source) { if (Source != nullptr) { Source->AssignTo(this); } else { AssignError(nullptr); } }
//----------------------------------------------------------------------------- // Build an array object from input text and returns the text position after // the parsed array const char* JSON::parseArray(const char* buff, const char** perror) { JSON *child; if (*buff!='[') { return AssignError(perror, "Syntax Error: Missing opening bracket"); } Type=JSON_Array; buff=skip(buff+1); if (*buff==']') return buff+1; // empty array. child = new JSON(); if (!child) return 0; // memory fail Children.PushBack(child); buff=skip(child->parseValue(skip(buff), perror)); // skip any spacing, get the buff. if (!buff) return 0; while (*buff==',') { JSON *new_item = new JSON(); if (!new_item) return AssignError(perror, "Error: Failed to allocate memory"); Children.PushBack(new_item); buff=skip(new_item->parseValue(skip(buff+1), perror)); if (!buff) return AssignError(perror, "Error: Failed to allocate memory"); } if (*buff==']') return buff+1; // end of array return AssignError(perror, "Syntax Error: Missing ending bracket"); }
//------------------------------------------------------------------------------ PrototypeMMOBaseEvent* TConverterEvents::Work(nsMMOEngine::TBaseEvent* pModuleEvent) { PrototypeMMOBaseEvent* pRes = NULL; switch(pModuleEvent->mType) { case nsMMOEngine::eConnectDown: pRes = AssignConnectDown((nsMMOEngine::TEventConnectDown*)pModuleEvent); break; case nsMMOEngine::eDisconnectDown: pRes = AssignDisconnectDown((nsMMOEngine::TEventDisconnectDown*)pModuleEvent); break; case nsMMOEngine::eConnectUp: pRes = AssignConnectUp((nsMMOEngine::TEventConnectUp*)pModuleEvent); break; case nsMMOEngine::eDisconnectUp: pRes = AssignDisconnectUp((nsMMOEngine::TEventDisconnectUp*)pModuleEvent); break; case nsMMOEngine::eError: pRes = AssignError((nsMMOEngine::TEventError*)pModuleEvent); break; case nsMMOEngine::eRecvFromDown: pRes = AssignRecvFromDown((nsMMOEngine::TEventRecvFromDown*)pModuleEvent); break; case nsMMOEngine::eRecvFromUp: pRes = AssignRecvFromUp((nsMMOEngine::TEventRecvFromUp*)pModuleEvent); break; case nsMMOEngine::eSaveContext: pRes = AssignSaveContext((nsMMOEngine::TEventSaveContext*)pModuleEvent); break; case nsMMOEngine::eRestoreContext: pRes = AssignRestoreContext((nsMMOEngine::TEventRestoreContext*)pModuleEvent); break; case nsMMOEngine::eTryLogin: pRes = AssignTryLogin((nsMMOEngine::TEventTryLogin*)pModuleEvent); break; case nsMMOEngine::eResultLogin: pRes = AssignResultLogin((nsMMOEngine::TEventResultLogin*)pModuleEvent); break; case nsMMOEngine::eDestroyGroup: pRes = AssignDestroyGroup((nsMMOEngine::TEventDestroyGroup*)pModuleEvent); break; case nsMMOEngine::eEnterInQueue: pRes = AssignEnterInQueue((nsMMOEngine::TEventEnterInQueue*)pModuleEvent); break; } pRes->c.Entrust(pModuleEvent->c.GetPtr(), pModuleEvent->c.GetSize()); pModuleEvent->c.Unlink(); return pRes; }
//----------------------------------------------------------------------------- // Parser core - when encountering text, process appropriately. const char* JSON::parseValue(const char* buff, const char** perror) { if (perror) *perror = 0; if (!buff) return NULL; // Fail on null. if (!strncmp(buff,"null",4)) { Type = JSON_Null; return buff+4; } if (!strncmp(buff,"false",5)) { Type = JSON_Bool; Value = "false"; dValue = 0.; return buff+5; } if (!strncmp(buff,"true",4)) { Type = JSON_Bool; Value = "true"; dValue = 1.; return buff + 4; } if (*buff=='\"') { return parseString(buff, perror); } if (*buff=='-' || (*buff>='0' && *buff<='9')) { return parseNumber(buff); } if (*buff=='[') { return parseArray(buff, perror); } if (*buff=='{') { return parseObject(buff, perror); } return AssignError(perror, "Syntax Error: Invalid syntax"); }
//----------------------------------------------------------------------------- // Parses the supplied buffer of JSON text and returns a JSON object tree // The returned object must be Released after use JSON* JSON::Parse(const char* buff, const char** perror) { const char* end = 0; JSON* json = new JSON(); if (!json) { AssignError(perror, "Error: Failed to allocate memory"); return 0; } end = json->parseValue(skip(buff), perror); if (!end) { json->Release(); return NULL; } // parse failure. ep is set. return json; }
//----------------------------------------------------------------------------- // Build an object from the supplied text and returns the text position after // the parsed object const char* JSON::parseObject(const char* buff, const char** perror) { if (*buff!='{') { return AssignError(perror, "Syntax Error: Missing opening brace"); } Type=JSON_Object; buff=skip(buff+1); if (*buff=='}') return buff+1; // empty array. JSON* child = new JSON(); Children.PushBack(child); buff=skip(child->parseString(skip(buff), perror)); if (!buff) return 0; child->Name = child->Value; child->Value.Clear(); if (*buff!=':') { return AssignError(perror, "Syntax Error: Missing colon"); } buff=skip(child->parseValue(skip(buff+1), perror)); // skip any spacing, get the value. if (!buff) return 0; while (*buff==',') { child = new JSON(); if (!child) return 0; // memory fail Children.PushBack(child); buff=skip(child->parseString(skip(buff+1), perror)); if (!buff) return 0; child->Name=child->Value; child->Value.Clear(); if (*buff!=':') { return AssignError(perror, "Syntax Error: Missing colon"); } // fail! // Skip any spacing, get the value. buff=skip(child->parseValue(skip(buff+1), perror)); if (!buff) return 0; } if (*buff=='}') return buff+1; // end of array return AssignError(perror, "Syntax Error: Missing closing brace"); }
//----------------------------------------------------------------------------- // Parses the input text into a string item and returns the text position after // the parsed string const char* JSON::parseString(const char* str, const char** perror) { const char* ptr = str+1; const char* p; char* ptr2; char* out; int len=0; unsigned uc, uc2; if (*str!='\"') { return AssignError(perror, "Syntax Error: Missing quote"); } while (*ptr!='\"' && *ptr && ++len) { if (*ptr++ == '\\') ptr++; // Skip escaped quotes. } // This is how long we need for the string, roughly. out=(char*)OVR_ALLOC(len+1); if (!out) return 0; ptr = str+1; ptr2= out; while (*ptr!='\"' && *ptr) { if (*ptr!='\\') { *ptr2++ = *ptr++; } else { ptr++; switch (*ptr) { case 'b': *ptr2++ = '\b'; break; case 'f': *ptr2++ = '\f'; break; case 'n': *ptr2++ = '\n'; break; case 'r': *ptr2++ = '\r'; break; case 't': *ptr2++ = '\t'; break; // Transcode utf16 to utf8. case 'u': // Get the unicode char. p = ParseHex(&uc, 4, ptr + 1); if (ptr != p) ptr = p - 1; if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; // Check for invalid. // UTF16 surrogate pairs. if (uc>=0xD800 && uc<=0xDBFF) { if (ptr[1]!='\\' || ptr[2]!='u') break; // Missing second-half of surrogate. p= ParseHex(&uc2, 4, ptr + 3); if (ptr != p) ptr = p - 1; if (uc2<0xDC00 || uc2>0xDFFF) break; // Invalid second-half of surrogate. uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); } len=4; if (uc<0x80) len=1; else if (uc<0x800) len=2; else if (uc<0x10000) len=3; ptr2+=len; switch (len) { case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; //no break, fall through case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; //no break case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; //no break case 1: *--ptr2 = (char)(uc | firstByteMark[len]); //no break } ptr2+=len; break; default: *ptr2++ = *ptr; break; } ptr++; } } *ptr2 = 0; if (*ptr=='\"') ptr++; // Make a copy of the string Value=out; OVR_FREE(out); Type=JSON_String; return ptr; }