//===========================================================================// // File: notation.hpp // // Title: Declaration of NotationFile classes. // // Project: Munga // // Author: Ken Olsen // // Purpose: Provide general purpose access to data stored in a formatted // // text file. // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 01/06/95 KEO Converted from Tool Architecture I. // // 02/07/95 KEO Add AppendEntry methods. // // 02/17/95 KEO Change page and entry lists to make nomenclature. // // 03/24/95 KEO Add methods to read and write text in memory. // // 03/31/95 KEO Add methods for lab only mark. // // 05/23/95 KEO Add getfilename, setpage and appendpage. // // 11/11/95 KEO Add operation modes and correct small bugs. // // 04/01/97 GAH Added "DeleteAllPages" method. // //---------------------------------------------------------------------------// // Copyright (c) 1994-1995 Virtual World Entertainment, Inc. // // Copyright (c) 1996-1997 Fasa Interactive Technologies, Inc. // // All rights reserved worldwide. // // This unpublished source code is PROPRIETARY and CONFIDENTIAL. // //===========================================================================// #pragma once #include "Stuff.hpp" #include "Scalar.hpp" #include "FileStream.hpp" #include "Tree.hpp" namespace Stuff { class NotationFile; class Page; class Note; class Macro { public: MString m_replacement; bool m_inUse; explicit Macro(MString *replace); static void AddValue( void *macro_tree, const char* name, const char* value ); static void ReplaceMacros( void *macro_tree, const char *buffer, char *new_buf, int new_buf_size ); void TestInstance() {} }; //======================================================================= // Format of notation file: // // !include file1.txt // !include=file1a.txt // !include "file2.txt" // // !example_macro=Field2Data // // // comment // // [RecordName] // comment // FieldName=FieldData // Field2Name=Field2Data // Field3Name=test.ini // // [Record2Name] // FieldName=FieldData // Field4Name=$(example_macro) // Field5Name={ // [Record3Name] // Field6Name=Whatever // } // // /* [Page3Name] // Field7Name=Uhhm // Field8Name=Uhhh */ // ... // //======================================================================= //########################################################################## //############## NotationFile ######################################## //########################################################################## class NotationFile #if defined(_ARMOR) : public Stuff::Signature #endif { friend class Page; friend class Note; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Constructor/Destructors // public: enum Type { Standard, NonEmpty, Raw }; NotationFile( const char *file_name, Type type=Standard, bool preserve_case=false ); explicit NotationFile(MemoryStream *stream=NULL); ~NotationFile(); void TestInstance() const; static bool TestClass(); static void *s_cachedIncludes; protected: NotationFile( MemoryStream *stream, void *macro_tree ); void CommonConstruction( MemoryStream *memory_stream, void *macro_tree ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Stream access // public: const FileDependencies* GetFileDependencies() const {Check_Object(this); return &m_fileDependencies;} const char* GetFileName() const {Check_Object(this); return m_fileName;} void SaveAs(const char* file_name); void Save(); void IgnoreChanges() {Check_Object(this); m_dirtyFlag = false;} bool IsChanged() const {Check_Object(this); return m_dirtyFlag;} void Write(MemoryStream *stream); protected: void Read( MemoryStream *stream, void *macro_tree, Page **page, bool nested ); void ProcessLine( MemoryStream *stream, void *macro_tree, Page **notepage, char* buffer ); void HandleBangStuff( char *buffer, void *macro_tree, Page **page ); void HandlePoundStuff( char *buffer, void *macro_tree, Page **page ); void SetDirty() { Check_Object(this); m_dirtyFlag = true; } Stuff::MString m_fileName; bool m_dirtyFlag, m_concatenate, m_preserveCase; Type m_type; FileDependencies m_fileDependencies; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Page access // public: bool IsEmpty() {Check_Object(this); return m_pages.IsEmpty();} bool DoesPageExist(const char *pagename) {Check_Object(this); return FindPage(pagename) != NULL;} Page* FindPage(const char* pagename); Page* GetPage(const char* pagename); typedef ChainIteratorOf PageIterator; PageIterator* MakePageIterator() {Check_Object(this); return new(g_Heap) PageIterator(&m_pages);} Page* AddPage(const char *pagename); Page* SetPage(const char *pagename); void DeletePage(const char *pagename); void DeleteAllPages(); protected: ChainOf m_pages; void* m_pageMap; }; }