DataChunk.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. ** Command & Conquer Generals Zero Hour(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. void writeNameKey(const NameKeyType key);
  119. };
  120. //----------------------------------------------------------------------
  121. // DataChunkInput
  122. //----------------------------------------------------------------------
  123. struct DataChunkInfo
  124. {
  125. AsciiString label;
  126. AsciiString parentLabel;
  127. DataChunkVersionType version;
  128. Int dataSize;
  129. };
  130. typedef Bool (*DataChunkParserPtr)( DataChunkInput &file, DataChunkInfo *info, void *userData );
  131. //----------------------------------------------------------------------
  132. // UserParser
  133. //----------------------------------------------------------------------
  134. class UserParser : public MemoryPoolObject
  135. {
  136. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(UserParser, "UserParser")
  137. public:
  138. UserParser *next;
  139. DataChunkParserPtr parser; // the user parsing function
  140. AsciiString label; // the data chunk label to match
  141. AsciiString parentLabel; // the parent chunk's label (the scope)
  142. void *userData; // user data pointer
  143. };
  144. EMPTY_DTOR(UserParser)
  145. //----------------------------------------------------------------------
  146. // DataChunkInput
  147. //----------------------------------------------------------------------
  148. class DataChunkInput
  149. {
  150. enum {CHUNK_HEADER_BYTES = 4}; // 2 shorts in chunk file header.
  151. protected:
  152. ChunkInputStream* m_file; // input file stream
  153. DataChunkTableOfContents m_contents; // table of contents of data chunk types
  154. Int m_fileposOfFirstChunk; // seek position of first data chunk
  155. UserParser* m_parserList; // list of all registered parsers for this input stream
  156. InputChunk* m_chunkStack; // current stack of open data chunks
  157. void clearChunkStack( void ); // clear the stack
  158. void decrementDataLeft( int size ); // update data left in chunk(s)
  159. public:
  160. void *m_currentObject; // user parse routines can use this to allow one chunk
  161. // to create an object, and a subsequent chunk to
  162. // parse values into that object. However, the second
  163. // chunk parser could also create and parse an object
  164. // of its own if this pointer is NULL.
  165. // The parser of the base class should NULL this pointer.
  166. void *m_userData; // user data hook
  167. public:
  168. DataChunkInput( ChunkInputStream *pStream );
  169. ~DataChunkInput();
  170. // register a parser function for data chunks with labels matching "label", whose parent
  171. // chunks labels match "parentLabel" (or NULL for global scope)
  172. void registerParser( const AsciiString& label, const AsciiString& parentLabel, DataChunkParserPtr parser, void *userData = NULL );
  173. Bool parse( void *userData = NULL ); // parse the chunk stream using registered parsers
  174. // assumed to be at the start of chunk when called
  175. // can be called recursively
  176. Bool isValidFileType(void); ///< Returns TRUE if it is our file format.
  177. AsciiString openDataChunk(DataChunkVersionType *ver );
  178. void closeDataChunk( void ); // close chunk and move to start of next chunk
  179. Bool atEndOfFile( void ) { return (m_file->eof()) ? true : false; } // return true if at end of file
  180. Bool atEndOfChunk( void ); // return true if all data has been read from this chunk
  181. void reset( void ); // reset to just-opened state
  182. AsciiString getChunkLabel( void ); // return label of current data chunk
  183. DataChunkVersionType getChunkVersion( void ); // return version of current data chunk
  184. unsigned int getChunkDataSize( void ); // return size of data stored in this chunk
  185. unsigned int getChunkDataSizeLeft( void ); // return size of data left to read in this chunk
  186. Real readReal(void);
  187. Int readInt(void);
  188. Byte readByte(void);
  189. AsciiString readAsciiString(void);
  190. UnicodeString readUnicodeString(void);
  191. Dict readDict(void);
  192. void readArrayOfBytes(char *ptr, Int len);
  193. NameKeyType readNameKey(void);
  194. };
  195. #endif // _DATA_CHUNK_H_