| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // DataChunk.h
- // Data chunk classes for saving and loading
- // Author: Michael S. Booth, October 2000
- #pragma once
- #ifndef _DATA_CHUNK_H_
- #define _DATA_CHUNK_H_
- #include "Common/GameMemory.h"
- #include "Common/Dict.h"
- #include "Common/MapReaderWriterInfo.h"
- typedef unsigned short DataChunkVersionType;
- // forward declarations
- class DataChunkInput;
- class DataChunkOutput;
- class DataChunkTableOfContents;
- //----------------------------------------------------------------------
- // Mapping
- //----------------------------------------------------------------------
- class Mapping : public MemoryPoolObject
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Mapping, "Mapping")
- public:
- Mapping* next;
- AsciiString name;
- UnsignedInt id;
- };
- EMPTY_DTOR(Mapping)
- //----------------------------------------------------------------------
- // OutputChunk
- //----------------------------------------------------------------------
- class OutputChunk : public MemoryPoolObject
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(OutputChunk, "OutputChunk")
- public:
- OutputChunk* next;
- UnsignedInt id; // chunk symbol type from table of contents
- Int filepos; // position of file at start of data offset
- };
- EMPTY_DTOR(OutputChunk)
- //----------------------------------------------------------------------
- // InputChunk
- //----------------------------------------------------------------------
- class InputChunk : public MemoryPoolObject
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(InputChunk, "InputChunk")
- public:
- InputChunk* next;
- UnsignedInt id; // chunk symbol type from table of contents
- DataChunkVersionType version; // version of data
- Int chunkStart; // tell position of the start of chunk data (past header).
- Int dataSize; // total data size of chunk
- Int dataLeft; // data left to read in this chunk
- };
- EMPTY_DTOR(InputChunk)
- //----------------------------------------------------------------------
- // DataChunkTableOfContents
- //----------------------------------------------------------------------
- class DataChunkTableOfContents
- {
- Mapping* m_list; /// @TODO: This should be a hash table
- Int m_listLength;
- UnsignedInt m_nextID; // simple ID allocator
- Bool m_headerOpened;
- Mapping *findMapping( const AsciiString& name ); // return mapping data
- public:
- DataChunkTableOfContents( void );
- ~DataChunkTableOfContents();
- UnsignedInt getID( const AsciiString& name ); // convert name to integer identifier
- AsciiString getName( UnsignedInt id ); // convert integer identifier to name
- UnsignedInt allocateID( const AsciiString& name ); // create new ID for given name or return existing mapping
- Bool isOpenedForRead(void) {return m_headerOpened;};
- void write(OutputStream &out);
- void read(ChunkInputStream &in);
- };
- //----------------------------------------------------------------------
- // DataChunkOutput
- //----------------------------------------------------------------------
- class DataChunkOutput
- {
- protected:
- OutputStream* m_pOut; // The actual output stream.
- FILE * m_tmp_file; // tmp output file stream
- DataChunkTableOfContents m_contents; // table of contents of data chunk types
- OutputChunk* m_chunkStack; // current stack of open data chunks
- public:
- DataChunkOutput( OutputStream *pOut );
- ~DataChunkOutput();
- void openDataChunk( char *name, DataChunkVersionType ver );
- void closeDataChunk( void );
- void writeReal(Real r);
- void writeInt(Int i);
- void writeByte(Byte b);
- void writeAsciiString(const AsciiString& string);
- void writeUnicodeString(UnicodeString string);
- void writeArrayOfBytes(char *ptr, Int len);
- void writeDict(const Dict& d);
- };
- //----------------------------------------------------------------------
- // DataChunkInput
- //----------------------------------------------------------------------
- struct DataChunkInfo
- {
- AsciiString label;
- AsciiString parentLabel;
- DataChunkVersionType version;
- Int dataSize;
- };
- typedef Bool (*DataChunkParserPtr)( DataChunkInput &file, DataChunkInfo *info, void *userData );
- //----------------------------------------------------------------------
- // UserParser
- //----------------------------------------------------------------------
- class UserParser : public MemoryPoolObject
- {
- MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(UserParser, "UserParser")
- public:
- UserParser *next;
- DataChunkParserPtr parser; // the user parsing function
- AsciiString label; // the data chunk label to match
- AsciiString parentLabel; // the parent chunk's label (the scope)
- void *userData; // user data pointer
- };
- EMPTY_DTOR(UserParser)
- //----------------------------------------------------------------------
- // DataChunkInput
- //----------------------------------------------------------------------
- class DataChunkInput
- {
- enum {CHUNK_HEADER_BYTES = 4}; // 2 shorts in chunk file header.
- protected:
- ChunkInputStream* m_file; // input file stream
- DataChunkTableOfContents m_contents; // table of contents of data chunk types
- Int m_fileposOfFirstChunk; // seek position of first data chunk
- UserParser* m_parserList; // list of all registered parsers for this input stream
- InputChunk* m_chunkStack; // current stack of open data chunks
- void clearChunkStack( void ); // clear the stack
- void decrementDataLeft( int size ); // update data left in chunk(s)
- public:
- void *m_currentObject; // user parse routines can use this to allow one chunk
- // to create an object, and a subsequent chunk to
- // parse values into that object. However, the second
- // chunk parser could also create and parse an object
- // of its own if this pointer is NULL.
- // The parser of the base class should NULL this pointer.
- void *m_userData; // user data hook
- public:
- DataChunkInput( ChunkInputStream *pStream );
- ~DataChunkInput();
- // register a parser function for data chunks with labels matching "label", whose parent
- // chunks labels match "parentLabel" (or NULL for global scope)
- void registerParser( const AsciiString& label, const AsciiString& parentLabel, DataChunkParserPtr parser, void *userData = NULL );
- Bool parse( void *userData = NULL ); // parse the chunk stream using registered parsers
- // assumed to be at the start of chunk when called
- // can be called recursively
- Bool isValidFileType(void); ///< Returns TRUE if it is our file format.
- AsciiString openDataChunk(DataChunkVersionType *ver );
- void closeDataChunk( void ); // close chunk and move to start of next chunk
- Bool atEndOfFile( void ) { return (m_file->eof()) ? true : false; } // return true if at end of file
- Bool atEndOfChunk( void ); // return true if all data has been read from this chunk
- void reset( void ); // reset to just-opened state
- AsciiString getChunkLabel( void ); // return label of current data chunk
- DataChunkVersionType getChunkVersion( void ); // return version of current data chunk
- unsigned int getChunkDataSize( void ); // return size of data stored in this chunk
- unsigned int getChunkDataSizeLeft( void ); // return size of data left to read in this chunk
- Real readReal(void);
- Int readInt(void);
- Byte readByte(void);
- AsciiString readAsciiString(void);
- UnicodeString readUnicodeString(void);
- Dict readDict(void);
- void readArrayOfBytes(char *ptr, Int len);
- };
- #endif // _DATA_CHUNK_H_
|