DataChunk.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // DataChunk.h
  24. // Data chunk classes for saving and loading
  25. // Author: Michael S. Booth, October 2000
  26. #pragma once
  27. #ifndef _DATA_CHUNK_H_
  28. #define _DATA_CHUNK_H_
  29. #include "Common/GameMemory.h"
  30. #include "Common/Dict.h"
  31. #include "Common/MapReaderWriterInfo.h"
  32. typedef unsigned short DataChunkVersionType;
  33. // forward declarations
  34. class DataChunkInput;
  35. class DataChunkOutput;
  36. class DataChunkTableOfContents;
  37. //----------------------------------------------------------------------
  38. // Mapping
  39. //----------------------------------------------------------------------
  40. class Mapping : public MemoryPoolObject
  41. {
  42. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Mapping, "Mapping")
  43. public:
  44. Mapping* next;
  45. AsciiString name;
  46. UnsignedInt id;
  47. };
  48. EMPTY_DTOR(Mapping)
  49. //----------------------------------------------------------------------
  50. // OutputChunk
  51. //----------------------------------------------------------------------
  52. class OutputChunk : public MemoryPoolObject
  53. {
  54. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(OutputChunk, "OutputChunk")
  55. public:
  56. OutputChunk* next;
  57. UnsignedInt id; // chunk symbol type from table of contents
  58. Int filepos; // position of file at start of data offset
  59. };
  60. EMPTY_DTOR(OutputChunk)
  61. //----------------------------------------------------------------------
  62. // InputChunk
  63. //----------------------------------------------------------------------
  64. class InputChunk : public MemoryPoolObject
  65. {
  66. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(InputChunk, "InputChunk")
  67. public:
  68. InputChunk* next;
  69. UnsignedInt id; // chunk symbol type from table of contents
  70. DataChunkVersionType version; // version of data
  71. Int chunkStart; // tell position of the start of chunk data (past header).
  72. Int dataSize; // total data size of chunk
  73. Int dataLeft; // data left to read in this chunk
  74. };
  75. EMPTY_DTOR(InputChunk)
  76. //----------------------------------------------------------------------
  77. // DataChunkTableOfContents
  78. //----------------------------------------------------------------------
  79. class DataChunkTableOfContents
  80. {
  81. Mapping* m_list; /// @TODO: This should be a hash table
  82. Int m_listLength;
  83. UnsignedInt m_nextID; // simple ID allocator
  84. Bool m_headerOpened;
  85. Mapping *findMapping( const AsciiString& name ); // return mapping data
  86. public:
  87. DataChunkTableOfContents( void );
  88. ~DataChunkTableOfContents();
  89. UnsignedInt getID( const AsciiString& name ); // convert name to integer identifier
  90. AsciiString getName( UnsignedInt id ); // convert integer identifier to name
  91. UnsignedInt allocateID( const AsciiString& name ); // create new ID for given name or return existing mapping
  92. Bool isOpenedForRead(void) {return m_headerOpened;};
  93. void write(OutputStream &out);
  94. void read(ChunkInputStream &in);
  95. };
  96. //----------------------------------------------------------------------
  97. // DataChunkOutput
  98. //----------------------------------------------------------------------
  99. class DataChunkOutput
  100. {
  101. protected:
  102. OutputStream* m_pOut; // The actual output stream.
  103. FILE * m_tmp_file; // tmp output file stream
  104. DataChunkTableOfContents m_contents; // table of contents of data chunk types
  105. OutputChunk* m_chunkStack; // current stack of open data chunks
  106. public:
  107. DataChunkOutput( OutputStream *pOut );
  108. ~DataChunkOutput();
  109. void openDataChunk( char *name, DataChunkVersionType ver );
  110. void closeDataChunk( void );
  111. void writeReal(Real r);
  112. void writeInt(Int i);
  113. void writeByte(Byte b);
  114. void writeAsciiString(const AsciiString& string);
  115. void writeUnicodeString(UnicodeString string);
  116. void writeArrayOfBytes(char *ptr, Int len);
  117. void writeDict(const Dict& d);
  118. };
  119. //----------------------------------------------------------------------
  120. // DataChunkInput
  121. //----------------------------------------------------------------------
  122. struct DataChunkInfo
  123. {
  124. AsciiString label;
  125. AsciiString parentLabel;
  126. DataChunkVersionType version;
  127. Int dataSize;
  128. };
  129. typedef Bool (*DataChunkParserPtr)( DataChunkInput &file, DataChunkInfo *info, void *userData );
  130. //----------------------------------------------------------------------
  131. // UserParser
  132. //----------------------------------------------------------------------
  133. class UserParser : public MemoryPoolObject
  134. {
  135. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(UserParser, "UserParser")
  136. public:
  137. UserParser *next;
  138. DataChunkParserPtr parser; // the user parsing function
  139. AsciiString label; // the data chunk label to match
  140. AsciiString parentLabel; // the parent chunk's label (the scope)
  141. void *userData; // user data pointer
  142. };
  143. EMPTY_DTOR(UserParser)
  144. //----------------------------------------------------------------------
  145. // DataChunkInput
  146. //----------------------------------------------------------------------
  147. class DataChunkInput
  148. {
  149. enum {CHUNK_HEADER_BYTES = 4}; // 2 shorts in chunk file header.
  150. protected:
  151. ChunkInputStream* m_file; // input file stream
  152. DataChunkTableOfContents m_contents; // table of contents of data chunk types
  153. Int m_fileposOfFirstChunk; // seek position of first data chunk
  154. UserParser* m_parserList; // list of all registered parsers for this input stream
  155. InputChunk* m_chunkStack; // current stack of open data chunks
  156. void clearChunkStack( void ); // clear the stack
  157. void decrementDataLeft( int size ); // update data left in chunk(s)
  158. public:
  159. void *m_currentObject; // user parse routines can use this to allow one chunk
  160. // to create an object, and a subsequent chunk to
  161. // parse values into that object. However, the second
  162. // chunk parser could also create and parse an object
  163. // of its own if this pointer is NULL.
  164. // The parser of the base class should NULL this pointer.
  165. void *m_userData; // user data hook
  166. public:
  167. DataChunkInput( ChunkInputStream *pStream );
  168. ~DataChunkInput();
  169. // register a parser function for data chunks with labels matching "label", whose parent
  170. // chunks labels match "parentLabel" (or NULL for global scope)
  171. void registerParser( const AsciiString& label, const AsciiString& parentLabel, DataChunkParserPtr parser, void *userData = NULL );
  172. Bool parse( void *userData = NULL ); // parse the chunk stream using registered parsers
  173. // assumed to be at the start of chunk when called
  174. // can be called recursively
  175. Bool isValidFileType(void); ///< Returns TRUE if it is our file format.
  176. AsciiString openDataChunk(DataChunkVersionType *ver );
  177. void closeDataChunk( void ); // close chunk and move to start of next chunk
  178. Bool atEndOfFile( void ) { return (m_file->eof()) ? true : false; } // return true if at end of file
  179. Bool atEndOfChunk( void ); // return true if all data has been read from this chunk
  180. void reset( void ); // reset to just-opened state
  181. AsciiString getChunkLabel( void ); // return label of current data chunk
  182. DataChunkVersionType getChunkVersion( void ); // return version of current data chunk
  183. unsigned int getChunkDataSize( void ); // return size of data stored in this chunk
  184. unsigned int getChunkDataSizeLeft( void ); // return size of data left to read in this chunk
  185. Real readReal(void);
  186. Int readInt(void);
  187. Byte readByte(void);
  188. AsciiString readAsciiString(void);
  189. UnicodeString readUnicodeString(void);
  190. Dict readDict(void);
  191. void readArrayOfBytes(char *ptr, Int len);
  192. };
  193. #endif // _DATA_CHUNK_H_