some improvements i think

This commit is contained in:
2026-01-14 20:15:49 +02:00
parent 6604c67ec5
commit 49adb21b81
14 changed files with 420 additions and 69 deletions

View File

@@ -5,28 +5,32 @@ abstract_class CJSONArray: public IJSONArray
{
public:
virtual uint32_t GetCount() override;
virtual IJSONObject *GetParameter( uint32_t i ) override;
virtual IJSONValue *GetParameter( uint32_t i ) override;
virtual void SetArray( uint32_t uCount, IJSONValue *pValue ) override;
virtual void SetArray( uint32_t uCount, IJSONValue **ppValues ) override;
virtual void CopyTo( IJSONArray *pObject ) override;
virtual void Free() override;
CUtlVector<IJSONValue*> m_values;
};
uint32_t CJSONArray::GetCount()
{
return m_values.GetSize();
}
IJSONObject *CJSONArray::GetParameter( uint32_t i )
IJSONValue *CJSONArray::GetParameter( uint32_t i )
{
return m_values[i];
}
void CJSONArray::SetArray( uint32_t uCount, IJSONValue *pValue )
void CJSONArray::SetArray( uint32_t uCount, IJSONValue **ppValues )
{
m_values.Resize(uCount);
for ( uint32_t u = 0; u < uCount; u++)
m_values[u] = ppValues[u];
}
void CJSONArray::CopyTo( IJSONArray *pObject )
@@ -36,7 +40,9 @@ void CJSONArray::CopyTo( IJSONArray *pObject )
void CJSONArray::Free()
{
for ( auto &value: m_values)
JSONManager()->FreeValue(value);
m_values = {};
}
abstract_class CJSONValue: public IJSONValue
@@ -118,30 +124,34 @@ void CJSONValue::MakeNULL()
void CJSONValue::SetStringValue( const char *szString )
{
MakeNULL();
m_eType = JSON_PARAMETER_STRING;
m_szString = szString;
}
void CJSONValue::SetNumberValue( float fValue )
{
MakeNULL();
m_eType = JSON_PARAMETER_NUMBER;
m_fValue = fValue;
}
void CJSONValue::SetBooleanValue( bool bValue )
{
MakeNULL();
m_eType = JSON_PARAMETER_BOOLEAN;
}
void CJSONValue::SetArrayValue( IJSONArray *pValue )
{
MakeNULL();
m_eType = JSON_PARAMETER_ARRAY;
m_pArray = pValue;
}
void CJSONValue::SetObjectValue( IJSONObject *pValue )
{
MakeNULL();
m_eType = JSON_PARAMETER_OBJECT;
m_pObject = pValue;
}
@@ -234,13 +244,17 @@ public:
virtual IJSONValue *CreateValue( ) override;
virtual void FreeValue( IJSONValue *pValue ) override;
virtual IJSONValue *ReadString( const char *szString ) override;
virtual CUtlString WriteString( IJSONValue *pValue ) override;
private:
CUtlString RealWriteString( IJSONValue *pValue, uint32_t uOffest );
static bool ExpectedToken( Token_t &token, const char *szValue );
static CUtlString GetQuotedToken( Token_t &token );
IJSONObject *ParseObject( Token_t *&pToken, const Token_t *pEnding );
IJSONArray *ParseArray( Token_t *&pToken, const Token_t *pEnding );
IJSONValue *ParseValue( Token_t *&pToken, const Token_t *pEnding );
virtual IJSONObject *ReadString( const char *szString ) override;
};
IJSONObject *CJSONManager::CreateObject( )
@@ -256,12 +270,13 @@ void CJSONManager::FreeObject( IJSONObject *pObject )
IJSONArray *CJSONManager::CreateArray( )
{
return new CJSONArray;
}
void CJSONManager::FreeArray( IJSONArray *pArray )
{
pArray->Free();
delete (CJSONObject*)pArray;
}
IJSONValue *CJSONManager::CreateValue( )
@@ -343,7 +358,7 @@ not_comma:
V_printf("%i: comma (,) or } was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
return NULL;
not_colon:
V_printf("%i: colon (:)was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
V_printf("%i: colon (:) was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
return NULL;
not_quoted:
@@ -357,22 +372,66 @@ eof:
IJSONArray *CJSONManager::ParseArray( Token_t *&pToken, const Token_t *pEnding )
{
IJSONArray *pObject;
CUtlString szParamName;
IJSONValue *pValue;
CUtlVector<IJSONValue*> values;
if ( !ExpectedToken(*(pToken), "[") )
return NULL;
NEXT_TOKEN();
pObject = CreateArray();
// object might be empty
if ( ExpectedToken(*pToken, "]") )
{
NEXT_TOKEN();
return pObject;
}
while(true)
{
pValue = ParseValue(pToken, pEnding);
values.AppendTail(pValue);
if ( !ExpectedToken(*pToken, ",") )
{
if ( !ExpectedToken(*pToken, "]") )
{
goto not_comma;
}
pObject->SetArray(values.GetSize(), values.GetData());
return pObject;
}
NEXT_TOKEN();
}
return pObject;
not_comma:
V_printf("%i: comma (,) or } was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
return NULL;
eof:
V_printf("EOF\n");
return NULL;
pObject->SetArray(values.GetSize(), values.GetData());
return pObject;
}
IJSONValue *CJSONManager::ParseValue( Token_t *&pToken, const Token_t *pEnding )
{
IJSONObject *pObject = ParseObject(pToken, pEnding);
IJSONArray *pArray = NULL;
IJSONArray *pArray = ParseArray(pToken, pEnding);
IJSONValue *pValue = CreateValue();
if (pObject)
{
pValue->SetObjectValue(pObject);
return pValue;
}
if (pArray)
{
pValue->SetArrayValue(pArray);
return pValue;
}
if ( GetQuotedToken(*pToken) != NULL )
{
pValue->SetStringValue(pToken->m_szValue);
@@ -386,19 +445,81 @@ eof:
}
IJSONObject *CJSONManager::ReadString( const char *psz )
IJSONValue *CJSONManager::ReadString( const char *psz )
{
CUtlVector<Token_t> tokens;
CUtlVector<char> stack;
IJSONObject *pGlobalObject = NULL;
IJSONValue *pGlobalObject = NULL;
tokens = Tokenize(psz);
Token_t *pCurrentToken = tokens.GetData();
pGlobalObject = ParseObject(pCurrentToken, tokens.end().m_pCurrent);
pGlobalObject = ParseValue(pCurrentToken, tokens.end().m_pCurrent);
return pGlobalObject;
};
CUtlString CJSONManager::WriteString( IJSONValue *pValue )
{
return RealWriteString(pValue, 0);
}
CUtlString CJSONManager::RealWriteString( IJSONValue *pValue, uint32_t uOffset )
{
IJSONArray *pArray;
CJSONObject *pObject;
CUtlString szString = "";
if (pValue)
switch (pValue->GetType())
{
case JSON_PARAMETER_NULL:
return CUtlString("null", pValue->GetNumberValue());
case JSON_PARAMETER_BOOLEAN:
if (pValue->GetBooleanValue())
return "true";
return "false";
case JSON_PARAMETER_NUMBER:
return CUtlString("\"%f\"", pValue->GetNumberValue());
case JSON_PARAMETER_STRING:
return CUtlString("\"%s\"", pValue->GetStringValue());
case JSON_PARAMETER_ARRAY:
pArray = pValue->GetArray();
szString.AppendTail("[\n");
for ( uint32_t i = 0; i < pArray->GetCount(); i++ )
{
for ( uint32_t j = 0; j <= uOffset; j++)
szString.AppendTail("\t");
szString.AppendTail(RealWriteString( pArray->GetParameter(i), uOffset+1 ));
if ( i != pArray->GetCount() - 1 )
szString.AppendTail(",");
szString.AppendTail("\n");
}
for ( uint32_t j = 0; j < uOffset; j++)
szString.AppendTail("\t");
szString.AppendTail("]");
return szString;
case JSON_PARAMETER_OBJECT:
pObject = (CJSONObject*)pValue->GetObject();
szString.AppendTail("{\n");
for ( uint32_t i = 0; i < pObject->m_params.GetSize(); i++ )
{
for ( uint32_t j = 0; j <= uOffset; j++)
szString.AppendTail("\t");
szString.AppendTail(pObject->m_params[i].m_szName);
szString.AppendTail(": ");
szString.AppendTail(RealWriteString( pObject->m_params[i].m_pValue, uOffset+1 ));
if ( i != pObject->m_params.GetSize() - 1 )
szString.AppendTail(",");
szString.AppendTail("\n");
}
for ( uint32_t j = 0; j < uOffset; j++)
szString.AppendTail("\t");
szString.AppendTail("}");
return szString;
}
}
IJSONManager *JSONManager()
{
static CJSONManager mgr;