//========= Copyright Valve Corporation, All rights reserved. ============// // // Purpose: // // $NoKeywords: $ //===========================================================================// #ifndef CHUNKFILE_H #define CHUNKFILE_H #ifdef _WIN32 #pragma once #endif #include #include "tokenreader.h" #define MAX_INDENT_DEPTH 80 #define MAX_KEYVALUE_LEN 1024 class CChunkFile; class Vector2D; class Vector; class Vector4D; // // Modes for Open. // enum ChunkFileOpenMode_t { ChunkFile_Read = 0, ChunkFile_Write, }; // // Return codes. // enum ChunkFileResult_t { ChunkFile_Ok = 0, ChunkFile_Fail, ChunkFile_OpenFail, ChunkFile_EndOfChunk, ChunkFile_EOF, ChunkFile_UnexpectedEOF, ChunkFile_UnexpectedSymbol, ChunkFile_OutOfMemory, ChunkFile_StringTooLong, ChunkFile_NotHandled }; enum ChunkType_t { ChunkType_Key = 0, ChunkType_Chunk, }; typedef ChunkFileResult_t (*DefaultChunkHandler_t)(CChunkFile *pFile, void *pData, char const *pChunkName); typedef ChunkFileResult_t (*ChunkHandler_t)(CChunkFile *pFile, void *pData); typedef ChunkFileResult_t (*KeyHandler_t)(const char *szKey, const char *szValue, void *pData); typedef bool (*ChunkErrorHandler_t)(CChunkFile *pFile, const char *szChunkName, void *pData); struct ChunkHandlerInfo_t { char szChunkName[80]; ChunkHandler_t pfnHandler; void *pData; }; struct ChunkHandlerInfoNode_t { ChunkHandlerInfo_t Handler; struct ChunkHandlerInfoNode_t *pNext; }; // // Consider handling chunks with handler objects instead of callbacks. // //class CChunkHandler //{ // virtual ChunkFileResult_t HandleChunk(const char *szName); // virtual ChunkFileResult_t HandleKey(const char *szKey, const char *szValue); // virtual bool HandleError(const char *szChunkName, ChunkFileResult_t eError); //}; class CChunkHandlerMap { public: CChunkHandlerMap(void); ~CChunkHandlerMap(void); void AddHandler(const char *pszChunkName, ChunkHandler_t pfnHandler, void *pData); ChunkHandler_t GetHandler(const char *pszChunkName, void **pData); void SetErrorHandler(ChunkErrorHandler_t pfnHandler, void *pData); ChunkErrorHandler_t GetErrorHandler(void **pData); protected: ChunkHandlerInfoNode_t *m_pHandlers; ChunkErrorHandler_t m_pfnErrorHandler; void *m_pErrorData; }; class CChunkFile { public: CChunkFile(void); ~CChunkFile(void); ChunkFileResult_t Open(const char *pszFileName, ChunkFileOpenMode_t eMode); ChunkFileResult_t Close(void); const char *GetErrorText(ChunkFileResult_t eResult); // // Functions for writing chunk files. // ChunkFileResult_t BeginChunk(const char *pszChunkName); ChunkFileResult_t EndChunk(void); ChunkFileResult_t WriteKeyValue(const char *pszKey, const char *pszValue); ChunkFileResult_t WriteKeyValueBool(const char *pszKey, bool bValue); ChunkFileResult_t WriteKeyValueColor(const char *pszKey, unsigned char r, unsigned char g, unsigned char b); ChunkFileResult_t WriteKeyValueFloat(const char *pszKey, float fValue); ChunkFileResult_t WriteKeyValueInt(const char *pszKey, int nValue); ChunkFileResult_t WriteKeyValuePoint(const char *pszKey, const Vector &Point); ChunkFileResult_t WriteKeyValueVector2(const char *pszKey, const Vector2D &vec); ChunkFileResult_t WriteKeyValueVector3(const char *pszKey, const Vector &vec); ChunkFileResult_t WriteKeyValueVector4( const char *pszKey, const Vector4D &vec); ChunkFileResult_t WriteLine(const char *pszLine); // // Functions for reading chunk files. // ChunkFileResult_t ReadChunk(KeyHandler_t pfnKeyHandler = NULL, void *pData = NULL); ChunkFileResult_t ReadNext(char *szKey, char *szValue, int nValueSize, ChunkType_t &eChunkType); ChunkFileResult_t HandleChunk(const char *szChunkName); void HandleError(const char *szChunkName, ChunkFileResult_t eError); // These functions should more really be named Parsexxx and possibly moved elsewhere. static bool ReadKeyValueBool(const char *pszValue, bool &bBool); static bool ReadKeyValueColor(const char *pszValue, unsigned char &chRed, unsigned char &chGreen, unsigned char &chBlue); static bool ReadKeyValueInt(const char *pszValue, int &nInt); static bool ReadKeyValueFloat(const char *pszValue, float &flFloat); static bool ReadKeyValuePoint(const char *pszValue, Vector &Point); static bool ReadKeyValueVector2(const char *pszValue, Vector2D &vec); static bool ReadKeyValueVector3(const char *pszValue, Vector &vec); static bool ReadKeyValueVector4( const char *pszValue, Vector4D &vec); // The default chunk handler gets called before any other chunk handlers. // // If the handler returns ChunkFile_Ok, then it goes into the chunk. // If the handler returns ChunkFile_NotHandled, then the chunk is // passed to the regular handlers. // // If you pass NULL in here, then it disables the default chunk handler. void SetDefaultChunkHandler( DefaultChunkHandler_t pHandler, void *pData ); void PushHandlers(CChunkHandlerMap *pHandlerMap); void PopHandlers(void); protected: void BuildIndentString(char *pszDest, int nDepth); TokenReader m_TokenReader; FILE *m_hFile; char m_szErrorToken[80]; char m_szIndent[MAX_INDENT_DEPTH]; int m_nCurrentDepth; // See SetDefaultChunkHandler.. DefaultChunkHandler_t m_DefaultChunkHandler; void *m_pDefaultChunkHandlerData; CChunkHandlerMap *m_HandlerStack[MAX_INDENT_DEPTH]; int m_nHandlerStackDepth; }; #endif // CHUNKFILE_H