http and lots of formats

This commit is contained in:
2026-01-05 00:30:37 +02:00
parent 965cecc901
commit f886350eb1
23 changed files with 1727 additions and 121 deletions

View File

@@ -142,8 +142,10 @@ IINIFile *CINIManager::ReadString( const char *psz )
if (bIsQuoted)
{
// text within ""
if (bIsSlash)
{
// reading \n \t etc.
bIsSlash = false;
switch (c)
{
@@ -157,8 +159,9 @@ IINIFile *CINIManager::ReadString( const char *psz )
szStringValue.AppendTail('\n');
continue;
case 't':
szStringValue.AppendTail('\n');
szStringValue.AppendTail('\t');
continue;
// allow for strings to go to next line with by ending with backward slash
case '\n':
szStringValue.AppendTail('\n');
continue;
@@ -167,16 +170,22 @@ IINIFile *CINIManager::ReadString( const char *psz )
continue;
}
} else {
// react to special symbols witin a string
switch (c)
{
// enables reading \n \t etc.
case '\\':
bIsSlash = true;
continue;
case '\n':
// newline
// we do want to end it to prevent parsing errors
// and there is no standart
V_printf("line %i: new line was found but the string wasn't finished, did you forget to place \" in the end of the line?\n", nCurrentLine);
case '"':
// end string
bIsQuoted = false;
if (szStringValue == 0)
continue;
@@ -190,6 +199,7 @@ IINIFile *CINIManager::ReadString( const char *psz )
}
} else {
// " makes it use a string
if (c == '"')
{
bIsQuoted = true;
@@ -210,6 +220,9 @@ IINIFile *CINIManager::ReadString( const char *psz )
};
// tokenize
// shitty tokenize
// must be reworked
for ( int i = 0; i < tokens.GetSize(); i++ )
{
if (tokens[i] == "]")

View File

@@ -0,0 +1,401 @@
#include "tier2/fileformats/json.h"
#include "tier2/tokenizer.h"
abstract_class CJSONArray: public IJSONArray
{
public:
virtual uint32_t GetCount() override;
virtual IJSONObject *GetParameter( uint32_t i ) override;
virtual void SetArray( uint32_t uCount, IJSONValue *pValue ) override;
virtual void CopyTo( IJSONArray *pObject ) override;
virtual void Free() override;
};
uint32_t CJSONArray::GetCount()
{
}
IJSONObject *CJSONArray::GetParameter( uint32_t i )
{
}
void CJSONArray::SetArray( uint32_t uCount, IJSONValue *pValue )
{
}
void CJSONArray::CopyTo( IJSONArray *pObject )
{
}
void CJSONArray::Free()
{
}
abstract_class CJSONValue: public IJSONValue
{
public:
virtual EJSONParameterType GetType( void ) override;
virtual const char *GetStringValue() override;
virtual float GetNumberValue() override;
virtual bool GetBooleanValue() override;
virtual IJSONArray *GetArray() override;
virtual IJSONObject *GetObject() override;
virtual void MakeNULL() override;
virtual void SetStringValue( const char *szString ) override;
virtual void SetNumberValue( float fValue ) override;
virtual void SetBooleanValue( bool bValue ) override;
virtual void SetArrayValue( IJSONArray *pValue ) override;
virtual void SetObjectValue( IJSONObject *pValue ) override;
virtual void CopyTo( IJSONValue *pObject ) override;
virtual void Free() override;
EJSONParameterType m_eType;
CUtlString m_szString;
float m_fValue;
bool m_bValue;
IJSONArray *m_pArray;
IJSONObject *m_pObject;
};
EJSONParameterType CJSONValue::GetType( void )
{
return m_eType;
}
const char * CJSONValue::GetStringValue()
{
return m_szString;
}
float CJSONValue::GetNumberValue()
{
return m_fValue;
}
bool CJSONValue::GetBooleanValue()
{
return m_fValue;
}
IJSONArray *CJSONValue::GetArray()
{
return m_pArray;
}
IJSONObject *CJSONValue::GetObject()
{
return m_pObject;
}
void CJSONValue::MakeNULL()
{
if ( GetType() == JSON_PARAMETER_OBJECT )
{
JSONManager()->FreeObject(m_pObject);
m_pObject = NULL;
}
if ( GetType() == JSON_PARAMETER_ARRAY )
{
JSONManager()->FreeArray(m_pArray);
m_pArray = NULL;
}
if ( GetType() == JSON_PARAMETER_STRING )
m_szString = NULL;
}
void CJSONValue::SetStringValue( const char *szString )
{
MakeNULL();
m_szString = szString;
}
void CJSONValue::SetNumberValue( float fValue )
{
MakeNULL();
m_fValue = fValue;
}
void CJSONValue::SetBooleanValue( bool bValue )
{
MakeNULL();
}
void CJSONValue::SetArrayValue( IJSONArray *pValue )
{
MakeNULL();
}
void CJSONValue::SetObjectValue( IJSONObject *pValue )
{
MakeNULL();
m_pObject = pValue;
}
void CJSONValue::CopyTo( IJSONValue *pObject )
{
MakeNULL();
}
void CJSONValue::Free()
{
MakeNULL();
}
abstract_class CJSONObject: public IJSONObject
{
public:
virtual IJSONValue *GetValue( const char *szName ) override;
virtual void SetValue( const char *szName, IJSONValue *pValue ) override;
virtual void CopyTo( IJSONObject *pObject ) override;
virtual void Free() override;
struct JSONObjectParam_t
{
CUtlString m_szName;
IJSONValue *m_pValue;
};
CUtlVector<JSONObjectParam_t> m_params;
};
IJSONValue *CJSONObject::GetValue( const char *szName )
{
int i;
JSONObjectParam_t *pParam;
for ( i = 0; i < m_params.GetSize(); i++ )
{
if ( m_params[i].m_szName != szName )
continue;
return m_params[i].m_pValue;
}
return NULL;
}
void CJSONObject::SetValue( const char *szName, IJSONValue *pValue )
{
int i;
JSONObjectParam_t *pParam;
for ( i = 0; i < m_params.GetSize(); i++ )
{
if ( m_params[i].m_szName != szName )
continue;
// Scary
if ( pValue == NULL )
m_params.RemoveAt(i);
else
m_params[i].m_pValue = pValue;
return;
}
if ( pValue == NULL )
return;
m_params.AppendTail({szName, pValue});
}
void CJSONObject::CopyTo( IJSONObject *pObject )
{
}
void CJSONObject::Free()
{
}
abstract_class CJSONManager: public IJSONManager
{
public:
virtual IJSONObject *CreateObject( ) override;
virtual void FreeObject( IJSONObject *pObject ) override;
virtual IJSONArray *CreateArray( ) override;
virtual void FreeArray( IJSONArray *pArray ) override;
virtual IJSONValue *CreateValue( ) override;
virtual void FreeValue( IJSONValue *pValue ) override;
private:
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( )
{
return new CJSONObject;
}
void CJSONManager::FreeObject( IJSONObject *pObject )
{
}
IJSONArray *CJSONManager::CreateArray( )
{
}
void CJSONManager::FreeArray( IJSONArray *pArray )
{
}
IJSONValue *CJSONManager::CreateValue( )
{
return new CJSONValue;
}
void CJSONManager::FreeValue( IJSONValue *pValue )
{
}
#define NEXT_TOKEN() \
pToken++; \
if (pToken == pEnding) \
goto eof \
bool CJSONManager::ExpectedToken( Token_t &token, const char *szValue )
{
if ( token.m_szValue == szValue && !token.m_bIsQuoted )
return true;
return false;
}
CUtlString CJSONManager::GetQuotedToken( Token_t &token )
{
if ( token.m_bIsQuoted )
return token.m_szValue;
return NULL;
}
IJSONObject *CJSONManager::ParseObject( Token_t *&pToken, const Token_t *pEnding )
{
IJSONObject *pObject;
CUtlString szParamName;
IJSONValue *pValue;
if ( !ExpectedToken(*(pToken), "{") )
return NULL;
NEXT_TOKEN();
pObject = CreateObject();
// object might be empty
if ( ExpectedToken(*pToken, "}") )
{
NEXT_TOKEN();
return pObject;
}
while(true)
{
szParamName = NULL;
pValue = NULL;
if ( GetQuotedToken(*pToken) == NULL )
goto not_quoted;
szParamName = pToken->m_szValue;
NEXT_TOKEN();
if ( !ExpectedToken(*pToken, ":") )
goto not_colon;
NEXT_TOKEN();
pValue = ParseValue(pToken, pEnding);
pObject->SetValue(szParamName, pValue);
if ( !ExpectedToken(*pToken, ",") )
{
if ( !ExpectedToken(*pToken, "}") )
{
goto not_comma;
}
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;
not_colon:
V_printf("%i: colon (:)was expected but got %s\n", pToken->m_iLine, pToken->m_szValue.GetString());
return NULL;
not_quoted:
V_printf("%s was not quoted\n", szParamName.GetString());
return NULL;
eof:
V_printf("EOF\n");
return NULL;
}
IJSONArray *CJSONManager::ParseArray( Token_t *&pToken, const Token_t *pEnding )
{
return NULL;
eof:
V_printf("EOF\n");
return NULL;
}
IJSONValue *CJSONManager::ParseValue( Token_t *&pToken, const Token_t *pEnding )
{
IJSONObject *pObject = ParseObject(pToken, pEnding);
IJSONArray *pArray = NULL;
IJSONValue *pValue = CreateValue();
if (pObject)
{
pValue->SetObjectValue(pObject);
return pValue;
}
if ( GetQuotedToken(*pToken) != NULL )
{
pValue->SetStringValue(pToken->m_szValue);
NEXT_TOKEN();
return pValue;
}
return NULL;
eof:
V_printf("EOF\n");
return NULL;
}
IJSONObject *CJSONManager::ReadString( const char *psz )
{
CUtlVector<Token_t> tokens;
CUtlVector<char> stack;
IJSONObject *pGlobalObject = NULL;
tokens = Tokenize(psz);
Token_t *pCurrentToken = tokens.GetData();
pGlobalObject = ParseObject(pCurrentToken, tokens.end().m_pCurrent);
return pGlobalObject;
};
IJSONManager *JSONManager()
{
static CJSONManager mgr;
return &mgr;
}

View File

@@ -0,0 +1,69 @@
#include "tier2/fileformats/xml.h"
#include "tier2/fileformats/plist.h"
class CPropertyListManager: public IPropertyListManager
{
public:
IJSONObject *ReadDict( IXMLObject *pDict );
virtual IJSONObject *ReadString( const char *psz ) override;
};
IJSONObject *CPropertyListManager::ReadString( const char *psz )
{
XMLFile_t file = XMLManager()->ReadString(psz);
IJSONObject *pObject;
IXMLObject *pList = file.m_pRoot->FindFirstTag(file.m_szRootObjectName);
if (pList == NULL)
return NULL;
IXMLObject *pDict = pList->FindFirstTag("dict");
if (pDict == NULL)
return NULL;
pObject = ReadDict(pDict);
return pObject;
}
IJSONObject *CPropertyListManager::ReadDict( IXMLObject *pDict )
{
CUtlString szKeyToCreate = NULL;
IJSONObject *pObject = JSONManager()->CreateObject();
for ( auto &c: pDict->GetChildren() )
{
if (c->GetType() != XML_OBJECT_ELEMENT)
continue;
if ( !V_strcmp(c->GetValue(), "key"))
{
szKeyToCreate = c->GetChildren()[0]->GetValue();
}
if ( !V_strcmp(c->GetValue(), "string"))
{
if ( szKeyToCreate == NULL )
continue;
IJSONValue *pVal = JSONManager()->CreateValue();
if (c->GetChildren().GetSize()>0)
pVal->SetStringValue(c->GetChildren()[0]->GetValue());
else
pVal->SetStringValue("");
pObject->SetValue(szKeyToCreate, pVal);
szKeyToCreate = NULL;
}
if ( !V_strcmp(c->GetValue(), "dict"))
{
if ( szKeyToCreate == NULL )
continue;
IJSONValue *pVal = JSONManager()->CreateValue();
pVal->SetObjectValue(ReadDict(c));
pObject->SetValue(szKeyToCreate, pVal);
szKeyToCreate = NULL;
}
}
return pObject;
}
IPropertyListManager *PropertyListManager()
{
static CPropertyListManager mgr = {};
return &mgr;
}

420
tier2/fileformats/xml.cpp Normal file
View File

@@ -0,0 +1,420 @@
#include "tier2/fileformats/xml.h"
#include "tier2/tokenizer.h"
class CXMLObject: public IXMLObject
{
public:
virtual EXMLObjectType GetType() override;
virtual const char *GetValue() override;
virtual void SetType( EXMLObjectType eType ) override;
virtual void SetValue( const char *psz ) override;
virtual CUtlVector<IXMLObject*> &GetChildren() override;
virtual CUtlVector<XMLParam_t> &GetParams() override;
virtual void Free() override;
EXMLObjectType m_eType;
CUtlString m_szValue;
CUtlVector<IXMLObject*> m_children;
CUtlVector<XMLParam_t> m_params;
};
EXMLObjectType CXMLObject::GetType()
{
return m_eType;
}
const char *CXMLObject::GetValue()
{
return m_szValue.GetString();
}
void CXMLObject::SetType( EXMLObjectType eType )
{
m_eType = eType;
}
void CXMLObject::SetValue( const char *psz )
{
m_szValue = psz;
}
CUtlVector<IXMLObject*> &CXMLObject::GetChildren()
{
return m_children;
}
CUtlVector<XMLParam_t> &CXMLObject::GetParams()
{
return m_params;
}
void CXMLObject::Free()
{
}
class CXMLManager: public IXMLManager
{
public:
virtual XMLFile_t ReadString( const char *szData ) override;
virtual CUtlString WriteString( IXMLObject *pObject ) override;
virtual IXMLObject *CreateObject() override;
virtual void FreeObject( IXMLObject *pObject ) override;
IXMLObject *ReadTagParams( CUtlString szTag );
XMLFile_t ReadDoctype( const char *szData );
bool BIsValidAtStart( char c );
bool BIsValidAtMid( char c );
void SkipWhiteSpaces( const char *&psz );
};
static char XML_TAG[] = "<";
static char XML_TAG_END[] = ">";
static char XML_SELF_CLOSE_END[] = "/>";
static char XML_CLOSE_TAG[] = "</";
static char XML_DOCTYPE[] = "<!DOCTYPE";
static char XML_PREPROCESSOR_BEGIN[] = "<?";
static char XML_PREPROCESSOR_END[] = "?>";
XMLFile_t CXMLManager::ReadString( const char *szString )
{
CUtlString szTagStack = {};
CUtlString szRootObjectName;
IXMLObject *pRootObject = CreateObject();
IXMLObject *pLastObject = pRootObject;
CUtlVector<IXMLObject*> stack = {pRootObject};
enum EXMLParsingMode
{
XML_PARSING_MODE_TEXT,
XML_PARSING_MODE_PREPROCESS_TAG,
XML_PARSING_MODE_TAG,
XML_PARSING_MODE_CLOSE_TAG,
XML_PARSING_MODE_DOCTYPE,
XML_PARSING_MODE_COMMENT,
} eMode = XML_PARSING_MODE_TEXT;
const char *psz = szString;
CUtlString szTag = "";
CUtlString szText = "";
XMLFile_t stFile = {};
while (*psz)
{
switch (eMode)
{
case XML_PARSING_MODE_TEXT:
if (!V_strncmp(XML_DOCTYPE, psz, sizeof(XML_DOCTYPE)-1))
{
psz+=sizeof(XML_DOCTYPE)-1;
szTag = NULL;
eMode = XML_PARSING_MODE_DOCTYPE;
if (szText != NULL)
{
IXMLObject *pText = CreateObject();
pText->SetType(XML_OBJECT_TEXT);
pText->SetValue(szText);
pLastObject->GetChildren().AppendTail(pText);
szText = NULL;
}
break;
}
if (!V_strncmp(XML_PREPROCESSOR_BEGIN, psz, sizeof(XML_PREPROCESSOR_BEGIN)-1))
{
psz+=sizeof(XML_PREPROCESSOR_BEGIN)-1;
szTag = NULL;
eMode = XML_PARSING_MODE_PREPROCESS_TAG;
if (szText != NULL)
{
IXMLObject *pText = CreateObject();
pText->SetType(XML_OBJECT_TEXT);
pText->SetValue(szText);
pLastObject->GetChildren().AppendTail(pText);
szText = NULL;
}
break;
}
if (!V_strncmp(XML_CLOSE_TAG, psz, sizeof(XML_CLOSE_TAG)-1))
{
psz+=sizeof(XML_CLOSE_TAG)-1;
szTag = NULL;
eMode = XML_PARSING_MODE_CLOSE_TAG;
if (szText != NULL)
{
IXMLObject *pText = CreateObject();
pText->SetType(XML_OBJECT_TEXT);
pText->SetValue(szText);
pLastObject->GetChildren().AppendTail(pText);
szText = NULL;
}
break;
}
if (!V_strncmp(XML_TAG, psz, sizeof(XML_TAG)-1))
{
psz+=sizeof(XML_TAG)-1;
szTag = NULL;
eMode = XML_PARSING_MODE_TAG;
if (szText != NULL)
{
IXMLObject *pText = CreateObject();
pText->SetType(XML_OBJECT_TEXT);
pText->SetValue(szText);
pLastObject->GetChildren().AppendTail(pText);
szText = NULL;
}
break;
}
szText.AppendTail(*psz);
psz++;
break;
case XML_PARSING_MODE_PREPROCESS_TAG:
if (!V_strncmp(XML_PREPROCESSOR_END, psz, sizeof(XML_PREPROCESSOR_END)-1))
{
psz+=sizeof(XML_PREPROCESSOR_END)-1;
eMode = XML_PARSING_MODE_TEXT;
V_printf("preprocess: %s\n", szTag.GetString());
break;
}
szTag.AppendTail(*psz);
psz++;
break;
case XML_PARSING_MODE_TAG:
if (!V_strncmp(XML_SELF_CLOSE_END, psz, sizeof(XML_SELF_CLOSE_END)-1))
{
psz+=sizeof(XML_SELF_CLOSE_END)-1;
eMode = XML_PARSING_MODE_TEXT;
IXMLObject *pObject = ReadTagParams(szTag);
pLastObject->GetChildren().AppendTail(pObject);
break;
}
if (!V_strncmp(XML_TAG_END, psz, sizeof(XML_TAG_END)-1))
{
psz+=sizeof(XML_TAG_END)-1;
eMode = XML_PARSING_MODE_TEXT;
IXMLObject *pObject = ReadTagParams(szTag);
stack.AppendTail(pObject);
pLastObject->GetChildren().AppendTail(pObject);
pLastObject = pObject;
break;
}
szTag.AppendTail(*psz);
psz++;
break;
case XML_PARSING_MODE_CLOSE_TAG:
if (!V_strncmp(XML_TAG_END, psz, sizeof(XML_TAG_END)-1))
{
psz+=sizeof(XML_TAG_END)-1;
eMode = XML_PARSING_MODE_TEXT;
if (!V_strcmp(pLastObject->GetValue(), szTag))
{
stack.RemoveTail();
pLastObject = stack[stack.GetSize()-1];
}
else
V_printf("\"%s\" != \"%s\"\n",pLastObject->GetValue(), szTag.GetString());
break;
}
szTag.AppendTail(*psz);
psz++;
break;
case XML_PARSING_MODE_DOCTYPE:
if (!V_strncmp(XML_TAG_END, psz, sizeof(XML_TAG_END)-1))
{
psz+=sizeof(XML_TAG_END)-1;
eMode = XML_PARSING_MODE_TEXT;
stFile = ReadDoctype(szTag);
break;
}
szTag.AppendTail(*psz);
psz++;
break;
case XML_PARSING_MODE_COMMENT:
break;
};
};
stFile.m_pRoot = pRootObject;
return stFile;
}
CUtlString CXMLManager::WriteString( IXMLObject *pObject )
{
};
IXMLObject *CXMLManager::ReadTagParams( CUtlString szTag )
{
const char *psz = szTag;
CUtlVector<XMLParam_t> params;
CUtlString szTagName = NULL;
CUtlString szParamName = NULL;
IXMLObject *pObject = CreateObject();
// Read tag name
if (!BIsValidAtStart(*psz))
{
V_printf("tag must start with letter or _");
FreeObject(pObject);
return NULL;
}
szTagName.AppendTail(*psz++);
while (BIsValidAtMid(*psz))
{
szTagName.AppendTail(*psz);
psz++;
}
pObject->SetType(XML_OBJECT_ELEMENT);
pObject->SetValue(szTagName);
while (*psz)
{
while (V_isspace(*psz))
{
psz++;
continue;
}
if (*psz && (!V_isalpha(*psz) || *psz == '_'))
{
V_printf("parameter must start with letter or _\n");
return {};
}
while (*psz && (*psz != ' ' || *psz != '='))
{
psz++;
continue;
}
while (V_isspace(*psz))
{
psz++;
continue;
}
szParamName.AppendTail(*psz);
};
return pObject;
};
static bool XMLGetWordSymbol( char c )
{
if (V_isalnum(c))
return true;
switch(c)
{
case ':':
return true;
case '.':
return true;
case '_':
return true;
case '-':
return true;
default:
break;
}
return false;
};
XMLFile_t CXMLManager::ReadDoctype( const char *szData )
{
const char *psz = szData;
XMLFile_t stFile = {};
CUtlString dtdType = NULL;
CUtlVector<Token_t> tokens;
int i = 0;
if (!V_isspace(*psz))
return stFile;
SkipWhiteSpaces(psz);
tokens = Tokenize(psz, XMLGetWordSymbol);
if ( tokens.GetSize() < i + 1 )
return stFile;
if ( tokens[i].m_bIsQuoted )
return stFile;
stFile.m_szRootObjectName = tokens[i++].m_szValue;
// parse ddt
if ( tokens.GetSize() < i + 1 )
return stFile;
if ( tokens[i].m_szValue == "PUBLIC" && !tokens[i].m_bIsQuoted )
{
i++;
if ( tokens.GetSize() < i + 2 )
return stFile;
if (!tokens[i].m_bIsQuoted || !tokens[i+1].m_bIsQuoted)
return stFile;
stFile.m_szFPI = tokens[i++].m_szValue;
stFile.m_szURI = tokens[i++].m_szValue;
} else if ( tokens[i].m_szValue == "SYSTEM" && !tokens[i].m_bIsQuoted )
{
} else
{
}
// read root element
return stFile;
}
bool CXMLManager::BIsValidAtStart( char c )
{
if (V_isalpha(c))
return true;
if (c == '_')
return true;
return false;
}
bool CXMLManager::BIsValidAtMid( char c )
{
if (V_isalnum(c))
return true;
if (c == '_')
return true;
if (c == '-')
return true;
if (c == '.')
return true;
return false;
}
void CXMLManager::SkipWhiteSpaces( const char *&psz )
{
while (V_isspace(*psz))
{
psz++;
continue;
}
}
IXMLObject *CXMLManager::CreateObject()
{
return new CXMLObject;
}
void CXMLManager::FreeObject( IXMLObject *pObject )
{
pObject->Free();
delete (CXMLObject*)pObject;
}
IXMLManager *XMLManager()
{
static CXMLManager mgr;
return &mgr;
};