1 //------------------------------------------------------------------------------
2 // File : SkyArchive.hpp
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 // The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its
8 // documentation for any purpose is hereby granted without fee, provided that
9 // the above copyright notice appear in all copies and that both that copyright
10 // notice and this permission notice appear in supporting documentation.
11 // Binaries may be compiled with this software without any royalties or
14 // The author(s) and The University of North Carolina at Chapel Hill make no
15 // representations about the suitability of this software for any purpose.
16 // It is provided "as is" without express or
19 * @file SkyArchive.hpp
21 * A hierarchical archive Class for storing data.
23 #ifndef __SKYARCHIVE_HPP__
24 #define __SKYARCHIVE_HPP__
26 // #pragma warning( disable : 4786 )
31 #include "SkyUtil.hpp"
33 #include <map> // for std::multimap
35 //! Types supported by the archive system
36 enum SkyArchiveTypeCode
56 struct SkyArchiveEntry;
58 struct StringLessFunctor
60 bool operator() (const char* p1, const char* p2) const
62 return ::strcmp( p1, p2) < 0;
66 //============================================================================
70 //! A simple hierarchical archive file useful for loading and saving data.
72 /*! SkyArchive bundles information so that an application can store,
73 manipulate, and retrieve data in a storage-independent manner. Information
74 stored in an SkyArchive file can be modified without breaking
75 compatibility with the code that retrieves the data. In essence, it can be
76 thought of as a very basic database mechanism.
78 A SkyArchive is simply a container. The class defines methods that allow
79 you to put information in a SkyArchive, determine the information in a
80 SkyArchive, and retrieve information from a SkyArchive. It's important
81 to note that the SkyArchive is a recursive storage mechanism; a
82 SkyArchive itself can hold one or more other SkyArchives.
84 Data are added to an archive in fields. The datum in a field is associated
85 with a name, number of bytes, and a type code. The name can be anything you
86 choose and is not required to be unique. The number of bytes must be accurate.
87 The type code must be one of the SkyArchiveTypeCode enums. Several of the Add
88 functions have been specialized for the common base types. It isn't necessary
89 to provide the number of bytes when using the specialized functions, since it can be
90 inferred from the type code.
92 The functions that retrieve fields from an archive are similar to the ones
93 that add data, only their roles are reversed. As with the Add functions,
94 there are several specialized functions for the common base types while
95 custom information can be retrieved using the generic FindData function.
97 Querying the contents of an archive is provided through the GetInfo
98 functions. These functions are important as they allow you to write
99 code that can intelligently determine how to retrieve information at
100 run-time: you no longer have to hardcode the order in which you retrieve
101 data from your files.
103 archive data fields are held in using an STL multimap. The multimap key
104 is a QString (field name) and the data is held in a SkyArchiveEntry
105 structure (see SkyArchive.cpp for details of this structure).
106 The fields are stored in alphabetical order based on the key names.
111 //=========================================================================
112 // Creation & Destruction
113 //=========================================================================
114 // Empty archive: no name, no data fields.
116 // Creates a named archive with no data fields.
117 SkyArchive( const char* pName);
118 // Deep copy the contents of one archive to another.
119 SkyArchive( const SkyArchive& src);
120 // Deep copy the contents of one archive to another.
121 SkyArchive& operator=( const SkyArchive& src);
125 //=========================================================================
126 // Basic SkyArchive Information
127 //=========================================================================
128 // Returns true if the archive contains no data fields.
129 bool IsEmpty() const;
130 //! Returns the archive's name.
131 const char* GetName() const { return _pName; };
133 //=========================================================================
134 // Adding Content to SkyArchive
135 //=========================================================================
136 // Adds a new datafield to the archive.
137 SKYRESULT AddData(const char* pName,
138 SkyArchiveTypeCode eType,
140 unsigned int iNumBytes,
141 unsigned int iNumItems = 1);
143 SKYRESULT AddBool( const char* pName, bool aBool);
144 SKYRESULT AddInt8( const char* pName, char anInt8);
145 SKYRESULT AddInt16( const char* pName, short anInt16);
146 SKYRESULT AddInt32( const char* pName, int anInt32);
147 SKYRESULT AddUInt8( const char* pName, unsigned char anUInt8);
148 SKYRESULT AddUInt16( const char* pName, unsigned short anUInt16);
149 SKYRESULT AddUInt32( const char* pName, unsigned int anUInt32);
150 SKYRESULT AddFloat32( const char* pName, float aFloat32);
151 SKYRESULT AddFloat64( const char* pName, double aFloat64);
152 SKYRESULT AddString( const char* pName, const char* pString);
154 SKYRESULT AddArchive( const SkyArchive& anArchive);
156 // Vector types (MJH:: only supports float versions for now!!!)
157 SKYRESULT AddVec2f( const char* pName, const Vec2f& aPoint2f);
158 SKYRESULT AddVec3f( const char* pName, const Vec3f& aPoint3f);
159 SKYRESULT AddVec4f( const char* pName, const Vec4f& aPoint4f);
161 //=========================================================================
162 // Retrieving Content from SkyArchive
163 //=========================================================================
164 // Retrieves the specified datafield the archive, if it exists.
165 SKYRESULT FindData( const char* pName,
166 SkyArchiveTypeCode eType,
168 unsigned int* pNumBytes,
169 unsigned int index = 0) const;
171 SKYRESULT FindBool( const char* pName, bool* pBool, unsigned int index = 0) const;
172 SKYRESULT FindInt8( const char* pName, char* pInt8, unsigned int index = 0) const;
173 SKYRESULT FindInt16( const char* pName, short* pInt16, unsigned int index = 0) const;
174 SKYRESULT FindInt32( const char* pName, int* pInt32, unsigned int index = 0) const;
175 SKYRESULT FindUInt8( const char* pName, unsigned char* pUInt8, unsigned int index = 0) const;
176 SKYRESULT FindUInt16( const char* pName, unsigned short* pUInt16, unsigned int index = 0) const;
177 SKYRESULT FindUInt32( const char* pName, unsigned int* pUInt32, unsigned int index = 0) const;
178 SKYRESULT FindFloat32(const char* pName, float* pFloat32, unsigned int index = 0) const;
179 SKYRESULT FindFloat64(const char* pName, double* pFloat64, unsigned int index = 0) const;
180 SKYRESULT FindString( const char* pName, char** const pString, unsigned int index = 0) const;
181 SKYRESULT FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index = 0) const;
183 SKYRESULT FindVec2f( const char* pName, Vec2f* pVec2f, unsigned int index = 0) const;
184 SKYRESULT FindVec3f( const char* pName, Vec3f* pVec3f, unsigned int index = 0) const;
185 SKYRESULT FindVec4f( const char* pName, Vec4f* pVec4f, unsigned int index = 0) const;
187 SKYRESULT AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index = 0) const;
189 //=========================================================================
190 // Querying Contents of SkyArchive
191 //=========================================================================
192 // Computes the number of fields that contain the given name and type.
193 SKYRESULT GetInfo(const char* pName,
194 SkyArchiveTypeCode eType,
195 unsigned int* pNumFound = NULL) const;
197 // Returns information about the key at the specified index.
198 SKYRESULT GetInfo(unsigned int iNameIndex,
200 SkyArchiveTypeCode* pTypeCode,
201 unsigned int* pNumFound);
203 // Computes the number of unique key names in _dataTableable.
204 unsigned int GetNumUniqueNames() const;
207 // Remove the contents of the SkyArchive.
208 SKYRESULT MakeEmpty();
210 // Loads the contents from a file.
211 SKYRESULT Load(const char* pFileName);
213 // Commits the contents of a SkyArchive to file storage.
214 SKYRESULT Save(const char* pFileName) const;
218 char* _pName; // this archive's name
220 //=========================================================================
222 //=========================================================================
223 typedef std::multimap<char*, SkyArchiveEntry*, StringLessFunctor> SkyArchiveMMap;
224 typedef SkyArchiveMMap::const_iterator SkyMMapConstIter;
225 typedef SkyArchiveMMap::iterator SkyMMapIter;
227 SkyArchiveMMap _dataTable; // this is where the data reside.
229 // Performs a deep-copy of one archive's archive_mmap_t to another.
230 void _CopyDataTable( const SkyArchiveMMap& src);
232 // Locates an archive entry in _dataTable
233 const SkyArchiveEntry* _FindEntry( const char* pName,
235 SkyArchiveTypeCode eType) const;
237 // Saves the archive to a file stream.
238 SKYRESULT _Save(FILE* pDestFile) const;
239 // Initializes the archive from a file stream.
240 SKYRESULT _Load(FILE* pSrcFile);
243 #endif //__SKYARCHIVE_HPP__