//-----------------------------------------------------------------------------
// 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;
}
Esempio n. 2
0
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");
}
Esempio n. 4
0
//------------------------------------------------------------------------------
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;
}