1 //------------------------------------------------------------------------------
2 // File : SkyArchive.cpp
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.cpp
21 * Implementation of class SkyArchive.
23 #include "SkyArchive.hpp"
27 struct SkyArchiveEntry
29 SkyArchiveEntry() : type(0), pData(NULL), iDataSize(0) {}
32 unsigned int iDataSize;
35 struct SkyArchiveFileEntry
37 SkyArchiveFileEntry() : type(0), iDataSize(0) {}
40 unsigned int iDataSize;
44 //------------------------------------------------------------------------------
45 // Function : SkyArchive::SkyArchive
47 //------------------------------------------------------------------------------
49 * @fn SkyArchive::SkyArchive()
50 * @brief Default constructor. Creates an empty, unnamed archive. |
52 SkyArchive::SkyArchive()
58 //------------------------------------------------------------------------------
59 // Function : SkyArchive::SkyArchive
61 //------------------------------------------------------------------------------
63 * @fn SkyArchive::SkyArchive(const char* pName)
64 * @brief Constructor. Creates an empty, named archive.
66 SkyArchive::SkyArchive(const char* pName)
68 _pName = new char[::strlen(pName)+1];
69 ::strcpy( _pName, pName);
73 //.---------------------------------------------------------------------------.
74 //| Function : SkyArchive::SkyArchive |
76 //.---------------------------------------------------------------------------.
78 //------------------------------------------------------------------------------
79 // Function : SkyArchive::SkyArchive
81 //------------------------------------------------------------------------------
83 * @fn SkyArchive::SkyArchive(const SkyArchive& src)
84 * @brief Copy constructor. Deep-copies the contents of one archive to another.
86 SkyArchive::SkyArchive(const SkyArchive& src)
88 _pName = new char[::strlen(src._pName)+1];
89 ::strcpy( _pName, src._pName);
91 _CopyDataTable( src._dataTable);
94 //------------------------------------------------------------------------------
95 // Function : SkyArchive::~SkyArchive
97 //------------------------------------------------------------------------------
99 * @fn SkyArchive::~SkyArchive()
102 SkyArchive::~SkyArchive()
105 SAFE_DELETE_ARRAY(_pName);
109 //.---------------------------------------------------------------------------.
110 //| Function : SkyArchive::operator= |
112 //.---------------------------------------------------------------------------.
114 //------------------------------------------------------------------------------
115 // Function : SkyArchive::operator=
117 //------------------------------------------------------------------------------
119 * @fn SkyArchive::operator=( const SkyArchive& src)
120 * @brief @todo Deep-copies the contents of one archive to another.
122 SkyArchive& SkyArchive::operator=( const SkyArchive& src)
127 SAFE_DELETE_ARRAY(_pName);
128 _pName = new char[::strlen(src._pName)+1];
129 ::strcpy( _pName, src.GetName());
131 _CopyDataTable( src._dataTable);
138 //=============================================================================
139 // Adding Content to SkyArchive
140 //=============================================================================
142 //------------------------------------------------------------------------------
143 // Function : SkyArchive::AddData
145 //------------------------------------------------------------------------------
147 * @fn SkyArchive::AddData(const char* pName,
148 SkyArchiveTypeCode eType,
150 unsigned int iNumBytes,
151 unsigned int iNumItems)
152 * @brief Adds a new data field to the archive.
154 * Makes a copy of the data, stores it in a SkyArchiveEntry, and adds it to the
155 * database. All specialized functions for the base types are implemented using
159 * @param name Field name. This is used as the key for the database entry.
160 * @param type Data type of the field.
161 * @param pData Pointer to the data to be added to the archive.
162 * @param iNumBytes Size of each individual item in the data
163 * @param iNumItems Number of items to copy
165 SKYRESULT SkyArchive::AddData(const char* pName,
166 SkyArchiveTypeCode eType,
168 unsigned int iNumBytes,
169 unsigned int iNumItems /* = 1 */)
171 // fill out a new archive entry with the supplied data
172 SkyArchiveEntry* pNewEntry = new SkyArchiveEntry;
173 pNewEntry->type = eType;
174 pNewEntry->iDataSize = iNumBytes * iNumItems;
176 if (eType != ARCHIVE_TYPE)
178 pNewEntry->pData = new unsigned char[pNewEntry->iDataSize];
179 ::memcpy(pNewEntry->pData, pData, pNewEntry->iDataSize);
183 pNewEntry->pData = (void*)pData;
186 char* pInternalName = new char[::strlen(pName)+1];
187 ::strcpy( pInternalName, pName);
188 _dataTable.insert(std::make_pair(pInternalName, pNewEntry));
194 //-----------------------------------------------------------------------------
195 // SkyArchive :: AddBool( const char* pName, bool aBool)
196 // SkyArchive :: AddInt8( const char* pName, Int8 anInt8)
197 // SkyArchive :: AddInt16( const char* pName, Int16 anInt16)
198 // SkyArchive :: AddInt32( const char* pName, Int32 anInt32)
200 //-----------------------------------------------------------------------------
202 // Specialized functions for the most common base types
204 //-----------------------------------------------------------------------------
207 //------------------------------------------------------------------------------
208 // Function : SkyArchive::AddBool
210 //------------------------------------------------------------------------------
212 * @fn SkyArchive::AddBool(const char* pName, bool aBool)
213 * @brief Adds a named bool to the archive.
215 SKYRESULT SkyArchive::AddBool(const char* pName, bool aBool)
217 return AddData( pName, BOOL_TYPE, &aBool, sizeof(bool));
220 //------------------------------------------------------------------------------
221 // Function : SkyArchive::AddInt8
223 //------------------------------------------------------------------------------
225 * @fn SkyArchive::AddInt8(const char* pName, char anInt8)
226 * @brief Adds a named 8-bit integer to the archive.
228 SKYRESULT SkyArchive::AddInt8(const char* pName, char anInt8)
230 return AddData( pName, INT8_TYPE, &anInt8, sizeof(char));
233 //------------------------------------------------------------------------------
234 // Function : SkyArchive::AddInt16
236 //------------------------------------------------------------------------------
238 * @fn SkyArchive::AddInt16(const char* pName, short anInt16)
239 * @brief Adds a named 16-bit integer to the archive.
241 SKYRESULT SkyArchive::AddInt16(const char* pName, short anInt16)
243 return AddData( pName, INT16_TYPE, &anInt16, sizeof(short));
246 //------------------------------------------------------------------------------
247 // Function : SkyArchive::AddInt32
249 //------------------------------------------------------------------------------
251 * @fn SkyArchive::AddInt32(const char* pName, int anInt32)
252 * @brief Adds a named 32-bit integer to the archive.
254 SKYRESULT SkyArchive::AddInt32(const char* pName, int anInt32)
256 return AddData( pName, INT32_TYPE, &anInt32, sizeof(int));
259 //------------------------------------------------------------------------------
260 // Function : SkyArchive::AddUInt8
262 //------------------------------------------------------------------------------
264 * @fn SkyArchive::AddUInt8(const char* pName, unsigned char anUInt8)
265 * @brief Adds a named unsigned 8-bit integer to the archive.
267 SKYRESULT SkyArchive::AddUInt8(const char* pName, unsigned char anUInt8)
269 return AddData( pName, UINT8_TYPE, &anUInt8, sizeof(unsigned char));
272 //------------------------------------------------------------------------------
273 // Function : SkyArchive::AddUInt16
275 //------------------------------------------------------------------------------
277 * @fn SkyArchive::AddUInt16(const char* pName, unsigned short anUInt16)
278 * @brief Adds a named unsigned 16-bit integer to the archive.
280 SKYRESULT SkyArchive::AddUInt16(const char* pName, unsigned short anUInt16)
282 return AddData( pName, UINT16_TYPE, &anUInt16, sizeof(unsigned short));
285 //------------------------------------------------------------------------------
286 // Function : SkyArchive::AddUInt32
288 //------------------------------------------------------------------------------
290 * @fn SkyArchive::AddUInt32(const char* pName, unsigned int anUInt32)
291 * @brief Adds a named unsigned 32-bit integer to the archive.
293 SKYRESULT SkyArchive::AddUInt32(const char* pName, unsigned int anUInt32)
295 return AddData( pName, UINT32_TYPE, &anUInt32, sizeof(unsigned int));
298 //------------------------------------------------------------------------------
299 // Function : SkyArchive::AddFloat32
301 //------------------------------------------------------------------------------
303 * @fn SkyArchive::AddFloat32(const char* pName, float aFloat32)
304 * @brief Adds a named 32-bit real number to the archive.
306 SKYRESULT SkyArchive::AddFloat32(const char* pName, float aFloat32)
308 return AddData( pName, FLOAT32_TYPE, &aFloat32, sizeof(float));
311 //------------------------------------------------------------------------------
312 // Function : SkyArchive::AddFloat64
314 //------------------------------------------------------------------------------
316 * @fn SkyArchive::AddFloat64(const char* pName, double aFloat64)
317 * @brief Adds a named 64-bit real number to the archive.
319 SKYRESULT SkyArchive::AddFloat64(const char* pName, double aFloat64)
321 return AddData( pName, FLOAT64_TYPE, &aFloat64, sizeof(double));
324 //------------------------------------------------------------------------------
325 // Function : SkyArchive::AddString
327 //------------------------------------------------------------------------------
329 * @fn SkyArchive::AddString(const char* pName, const char* pString)
330 * @brief Adds a named string to the archive.
332 SKYRESULT SkyArchive::AddString(const char* pName, const char* pString)
334 return AddData( pName, STRING_TYPE, pString, ::strlen(pString)+1);
337 //------------------------------------------------------------------------------
338 // Function : SkyArchive::AddArchive
340 //------------------------------------------------------------------------------
342 * @fn SkyArchive::AddArchive(const SkyArchive& anArchive)
343 * @brief Adds a subarchive to this archive.
345 * This method allows hierarchical data structures to be stored in an archive.
347 SKYRESULT SkyArchive::AddArchive(const SkyArchive& anArchive)
349 SkyArchive* pCopy = new SkyArchive(anArchive);
350 return AddData( pCopy->GetName(), ARCHIVE_TYPE, pCopy, sizeof(SkyArchive));
353 //-----------------------------------------------------------------------------
354 // Adding Vector types
355 //-----------------------------------------------------------------------------
357 //------------------------------------------------------------------------------
358 // Function : SkyArchive::AddVec2f
360 //------------------------------------------------------------------------------
362 * @fn SkyArchive::AddVec2f(const char* pName, const Vec2f& aVec2f)
363 * @brief Adds a 2-component 32-bit real number vector to the archive.
365 SKYRESULT SkyArchive::AddVec2f(const char* pName, const Vec2f& aVec2f)
367 return AddData( pName, VEC2F_TYPE, &aVec2f, sizeof(Vec2f));
370 //------------------------------------------------------------------------------
371 // Function : SkyArchive::AddVec3f
373 //------------------------------------------------------------------------------
375 * @fn SkyArchive::AddVec3f(const char* pName, const Vec3f& aVec3f)
376 * @brief Adds a 3-component 32-bit real number vector to the archive.
378 SKYRESULT SkyArchive::AddVec3f(const char* pName, const Vec3f& aVec3f)
380 return AddData( pName, VEC3F_TYPE, &aVec3f, sizeof(Vec3f));
383 //------------------------------------------------------------------------------
384 // Function : SkyArchive::AddVec4f
386 //------------------------------------------------------------------------------
388 * @fn SkyArchive::AddVec4f(const char* pName, const Vec4f& aVec4f)
389 * @brief Adds a 4-component 32-bit real number vector to the archive.
391 SKYRESULT SkyArchive::AddVec4f(const char* pName, const Vec4f& aVec4f)
393 return AddData( pName, VEC4F_TYPE, &aVec4f, sizeof(Vec4f));
396 //=============================================================================
397 // Retrieving Content from SkyArchive
398 //=============================================================================
400 //------------------------------------------------------------------------------
401 // Function : SkyArchive::FindData
403 //------------------------------------------------------------------------------
405 * @fn SkyArchive::FindData(const char* pName,
406 SkyArchiveTypeCode eType,
408 unsigned int* pNumBytes,
409 unsigned int index) const
410 * @brief Retrieves datafield from _dataTable.
413 * @param name The field name. used as the key for the multimap entry.
414 * @param type Data type of the field.
415 * @param pData Pointer to the returned data.
416 * @param pNumBytes Returns the size of the field entry returned.
417 * @param index Which item of the given \a name to locate.
419 SKYRESULT SkyArchive::FindData(const char* pName,
420 SkyArchiveTypeCode eType,
422 unsigned int* pNumBytes,
423 unsigned int index /* = 0 */) const
425 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, eType);
430 *pData = new unsigned char[pEntry->iDataSize];
431 ::memcpy( ((void*)*pData), pEntry->pData, pEntry->iDataSize);
436 *pNumBytes = pEntry->iDataSize;
441 return SKYRESULT_FAIL;
445 //-----------------------------------------------------------------------------
446 // SkyArchive :: FindBool( const char* pName, bool* aBool)
447 // SkyArchive :: FindInt8( const char* pName, Int8* anInt8)
448 // SkyArchive :: FindInt16( const char* pName, Int16* anInt16)
449 // SkyArchive :: FindInt32( const char* pName, Int32* anInt32)
451 //-----------------------------------------------------------------------------
453 // specialized function for the most common base types
455 //-----------------------------------------------------------------------------
457 //------------------------------------------------------------------------------
458 // Function : SkyArchive::FindBool
460 //------------------------------------------------------------------------------
462 * @fn SkyArchive::FindBool(const char* pName, bool* pBool, unsigned int index) const
463 * @brief Finds a named bool in the archive.
465 SKYRESULT SkyArchive::FindBool(const char* pName, bool* pBool, unsigned int index) const
467 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, BOOL_TYPE);
470 bool* pData = (bool*)(pEntry->pData);
474 return SKYRESULT_FAIL;
477 //------------------------------------------------------------------------------
478 // Function : SkyArchive::FindInt8
480 //------------------------------------------------------------------------------
482 * @fn SkyArchive::FindInt8(const char* pName, char* pInt8, unsigned int index) const
483 * @brief Finds a named 8-bit integer in the archive.
485 SKYRESULT SkyArchive::FindInt8(const char* pName, char* pInt8, unsigned int index) const
487 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT8_TYPE);
490 char* pData = (char*)(pEntry->pData);
494 return SKYRESULT_FAIL;
497 //------------------------------------------------------------------------------
498 // Function : SkyArchive::FindInt16
500 //------------------------------------------------------------------------------
502 * @fn SkyArchive::FindInt16(const char* pName, short* pInt16, unsigned int index) const
503 * @brief Finds a named 16-bit integer in the archive.
505 SKYRESULT SkyArchive::FindInt16(const char* pName, short* pInt16, unsigned int index) const
507 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT16_TYPE);
510 short* pData = (short*)(pEntry->pData);
514 return SKYRESULT_FAIL;
517 //------------------------------------------------------------------------------
518 // Function : SkyArchive::FindInt32
520 //------------------------------------------------------------------------------
522 * @fn SkyArchive::FindInt32(const char* pName, int* pInt32, unsigned int index) const
523 * @brief Finds a named 32-bit integer in the archive.
525 SKYRESULT SkyArchive::FindInt32(const char* pName, int* pInt32, unsigned int index) const
527 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT32_TYPE);
530 int* pData = (int*)(pEntry->pData);
534 return SKYRESULT_FAIL;
537 //------------------------------------------------------------------------------
538 // Function : SkyArchive::FindUInt8
540 //------------------------------------------------------------------------------
542 * @fn SkyArchive::FindUInt8(const char* pName, unsigned char* pUInt8, unsigned int index) const
543 * @brief Finds a named unsigned 8-bit integer in the archive.
545 SKYRESULT SkyArchive::FindUInt8(const char* pName, unsigned char* pUInt8, unsigned int index) const
547 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, UINT8_TYPE);
550 unsigned char* pData = (unsigned char*)(pEntry->pData);
554 return SKYRESULT_FAIL;
557 //------------------------------------------------------------------------------
558 // Function : SkyArchive::FindUInt16
560 //------------------------------------------------------------------------------
562 * @fn SkyArchive::FindUInt16(const char* pName, unsigned short* pUInt16, unsigned int index) const
563 * @brief Finds a named unsigned 16-bit integer in the archive.
565 SKYRESULT SkyArchive::FindUInt16(const char* pName, unsigned short* pUInt16, unsigned int index) const
567 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, UINT16_TYPE);
570 unsigned short* pData = (unsigned short*)(pEntry->pData);
574 return SKYRESULT_FAIL;
577 //------------------------------------------------------------------------------
578 // Function : SkyArchive::FindUInt32
580 //------------------------------------------------------------------------------
582 * @fn SkyArchive::FindUInt32(const char* pName, unsigned int* pUInt32, unsigned int index) const
583 * @brief Finds a named unsigned 32-bit integer in the archive.
585 SKYRESULT SkyArchive::FindUInt32(const char* pName, unsigned int* pUInt32, unsigned int index) const
587 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, UINT32_TYPE);
590 unsigned int* pData = (unsigned int*)(pEntry->pData);
594 return SKYRESULT_FAIL;
597 //------------------------------------------------------------------------------
598 // Function : SkyArchive::FindFloat32
600 //------------------------------------------------------------------------------
602 * @fn SkyArchive::FindFloat32(const char* pName, float* pFloat32, unsigned int index) const
603 * @brief Finds a named 32-bit real number in the archive.
605 SKYRESULT SkyArchive::FindFloat32(const char* pName, float* pFloat32, unsigned int index) const
607 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, FLOAT32_TYPE);
610 float* pData = (float*)(pEntry->pData);
614 return SKYRESULT_FAIL;
617 //------------------------------------------------------------------------------
618 // Function : SkyArchive::FindFloat64
620 //------------------------------------------------------------------------------
622 * @fn SkyArchive::FindFloat64(const char* pName, double* pFloat64, unsigned int index) const
623 * @brief Finds a named 64-bit real number in the archive.
625 SKYRESULT SkyArchive::FindFloat64(const char* pName, double* pFloat64, unsigned int index) const
627 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, FLOAT64_TYPE);
630 double* pData = (double*)(pEntry->pData);
634 return SKYRESULT_FAIL;
637 //------------------------------------------------------------------------------
638 // Function : SkyArchive::FindString
640 //------------------------------------------------------------------------------
642 * @fn SkyArchive::FindString(const char* pName, char** const pString, unsigned int index) const
643 * @brief Finds a named string in the archive.
645 SKYRESULT SkyArchive::FindString(const char* pName, char** const pString, unsigned int index) const
647 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, STRING_TYPE);
650 char* pData = (char*)(pEntry->pData);
651 *pString = new char[pEntry->iDataSize];
652 ::strcpy((char*)*pString, pData);
655 return SKYRESULT_FAIL;
658 //------------------------------------------------------------------------------
659 // Function : SkyArchive::FindArchive
661 //------------------------------------------------------------------------------
663 * @fn SkyArchive::FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index) const
664 * @brief Finds a named sub-archive in the archive.
666 SKYRESULT SkyArchive::FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index) const
668 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, ARCHIVE_TYPE);
671 SkyArchive* pData = (SkyArchive*)(pEntry->pData);
675 return SKYRESULT_FAIL;
678 //------------------------------------------------------------------------------
679 // Function : SkyArchive::FindVec2f
681 //------------------------------------------------------------------------------
683 * @fn SkyArchive::FindVec2f(const char* pName, Vec2f* pVec2f, unsigned int index) const
684 * @brief Finds a 2-component 32-bit real number vector in the archive.
686 SKYRESULT SkyArchive::FindVec2f(const char* pName, Vec2f* pVec2f, unsigned int index) const
688 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, VEC2F_TYPE);
691 Vec2f* pData = (Vec2f*)(pEntry->pData);
695 return SKYRESULT_FAIL;
698 //------------------------------------------------------------------------------
699 // Function : SkyArchive::FindVec3f
701 //------------------------------------------------------------------------------
703 * @fn SkyArchive::FindVec3f(const char* pName, Vec3f* pVec3f, unsigned int index) const
704 * @brief Finds a 3-component 32-bit real number vector in the archive.
706 SKYRESULT SkyArchive::FindVec3f(const char* pName, Vec3f* pVec3f, unsigned int index) const
708 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, VEC3F_TYPE);
711 Vec3f* pData = (Vec3f*)(pEntry->pData);
715 return SKYRESULT_FAIL;
718 //------------------------------------------------------------------------------
719 // Function : SkyArchive::FindVec4f
721 //------------------------------------------------------------------------------
723 * @fn SkyArchive::FindVec4f(const char* pName, Vec4f* pVec4f, unsigned int index) const
724 * @brief Finds a 4-component 32-bit real number vector in the archive.
726 SKYRESULT SkyArchive::FindVec4f(const char* pName, Vec4f* pVec4f, unsigned int index) const
728 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, VEC4F_TYPE);
731 Vec4f* pData = (Vec4f*)(pEntry->pData);
735 return SKYRESULT_FAIL;
738 //------------------------------------------------------------------------------
739 // Function : SkyArchive::AccessArchive
741 //------------------------------------------------------------------------------
743 * @fn SkyArchive::AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index) const
744 * @brief Accesses a named sub-archive in an archive directly.
746 * Note: The data are not copied!
748 SKYRESULT SkyArchive::AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index) const
750 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, ARCHIVE_TYPE);
753 SkyArchive* pData = (SkyArchive*)(pEntry->pData);
757 return SKYRESULT_FAIL;
761 //------------------------------------------------------------------------------
762 // Function : SkyArchive::GetInfo
764 //------------------------------------------------------------------------------
766 * @fn SkyArchive::GetInfo(const char* pName, SkyArchiveTypeCode eType, unsigned int* pNumFound) const
767 * @brief Computes the number of fields that contain the given name and type.
770 * @param pName Field name to search for.
771 * @param eType Field type to search for.
772 * @param pNumFound Returns the number of fields that contain given name and type.
774 SKYRESULT SkyArchive::GetInfo(const char* pName,
775 SkyArchiveTypeCode eType,
776 unsigned int* pNumFound) const
779 // Find the range of entries in the mmap with the key matching pName
781 std::pair<SkyMMapConstIter, SkyMMapConstIter> b = _dataTable.equal_range((char*)pName);
783 unsigned int count = 0;
784 for ( SkyMMapConstIter i = b.first; i != b.second; ++i )
787 // The entry's type must match...
789 const SkyArchiveEntry* pEntry = (*i).second;
790 if (pEntry->type == eType || ANY_TYPE == eType)
792 // only increment the count when the type matches
803 return SKYRESULT_FAIL;
809 //------------------------------------------------------------------------------
810 // Function : SkyArchive::GetInfo
812 //------------------------------------------------------------------------------
814 * @fn SkyArchive::GetInfo(unsigned int iNameIndex, char** pNameFound, SkyArchiveTypeCode* pTypeCode, unsigned int* pNumFound)
815 * @brief Returns information about the key at the specified index.
818 * @param nameIndex Key index to look up.
819 * @param pNameFound Key name is returned here.
820 * @param pTypeCode Key type is returned here.
821 * @param pNumFound Number of fields held under key name is returned here.
823 SKYRESULT SkyArchive::GetInfo(unsigned int iNameIndex,
825 SkyArchiveTypeCode* pTypeCode,
826 unsigned int* pNumFound)
828 assert( pNameFound != NULL);
831 return SKYRESULT_FAIL;
833 unsigned int iCurrentKeyIndex = 0;
834 SkyMMapConstIter iter;
835 const char* pLastKey = "";
837 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
839 const char* pKey = (*iter).first;
840 if (::strcmp( pLastKey, pKey))
842 if (iCurrentKeyIndex == iNameIndex)
844 *pNameFound = new char[::strlen(pKey) + 1];
845 ::strcpy(*pNameFound, pKey);
849 const SkyArchiveEntry* pEntry = (*iter).second;
850 *pTypeCode = (SkyArchiveTypeCode)pEntry->type;
855 return GetInfo( *pNameFound, *pTypeCode, pNumFound);
864 return SKYRESULT_FAIL;
868 //------------------------------------------------------------------------------
869 // Function : SkyArchive::GetNumUniqueNames
871 //------------------------------------------------------------------------------
873 * @fn SkyArchive::GetNumUniqueNames() const
874 * @brief Computes the number of unique key names in _dataTable.
876 unsigned int SkyArchive::GetNumUniqueNames() const
882 unsigned int iNumKeys = 0;
883 SkyMMapConstIter iter;
884 const char* pLastKey = "";
886 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
888 const char* pKey = (*iter).first;
889 if (::strcmp( pLastKey, pKey))
899 //=============================================================================
900 // Removing Contents of SkyArchive
901 //=============================================================================
903 //------------------------------------------------------------------------------
904 // Function : SkyArchive::MakeEmpty
906 //------------------------------------------------------------------------------
908 * @fn SkyArchive::MakeEmpty()
909 * @brief Remove all the contents of the database.
911 SKYRESULT SkyArchive::MakeEmpty()
915 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
917 SkyArchiveEntry* pEntry = (*iter).second;
918 char* pName = (*iter).first;
919 SAFE_DELETE_ARRAY(pName);
921 if (ARCHIVE_TYPE == pEntry->type)
923 SkyArchive* pArchive = (SkyArchive*)(pEntry->pData);
924 SAFE_DELETE(pArchive);
928 SAFE_DELETE_ARRAY(pEntry->pData);
938 //------------------------------------------------------------------------------
939 // Function : SkyArchive::IsEmpty
941 //------------------------------------------------------------------------------
943 * @fn SkyArchive::IsEmpty() const
944 * @brief returns true if the archive is empty, false if it contains any data.
946 bool SkyArchive::IsEmpty() const
948 return (0 == _dataTable.size());
952 //------------------------------------------------------------------------------
953 // Function : SkyArchive::Load
955 //------------------------------------------------------------------------------
957 * @fn SkyArchive::Load(const char* pFileName)
958 * @brief Load the contents of a SkyArchive from file storage.
960 SKYRESULT SkyArchive::Load(const char* pFileName)
963 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::Load(): file name is NULL.");
965 FILE* pSrcFile = NULL;
967 if (NULL == (pSrcFile = fopen(pFileName, "rb"))) // file opened successfully
969 SkyTrace("Error: SkyArchive::Load(): failed to open file for reading.");
970 return SKYRESULT_FAIL;
973 SKYRESULT retVal = _Load(pSrcFile);
980 //------------------------------------------------------------------------------
981 // Function : SkyArchive::Commit
983 //------------------------------------------------------------------------------
985 * @fn SkyArchive::Save(const char* pFilename) const
986 * @brief Commit Contents of SkyArchive to file storage.
988 SKYRESULT SkyArchive::Save(const char* pFileName) const
991 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::Save(): file name is NULL.");
993 FILE* pDestFile = NULL;
995 if (NULL == (pDestFile = fopen(pFileName, "wb"))) // file opened successfully
996 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::Save(): failed to open file for writing.");
998 SKYRESULT retVal = _Save(pDestFile);
1002 FAIL_RETURN(retVal);
1003 return SKYRESULT_OK;
1007 //=============================================================================
1008 // Private helper functions
1009 //=============================================================================
1011 //------------------------------------------------------------------------------
1012 // Function : SkyArchive::_FindEntry
1014 //------------------------------------------------------------------------------
1016 * @fn SkyArchive::_FindEntry(const char* pName, unsigned int index, SkyArchiveTypeCode eType) const
1017 * @brief Locates and returns the SkyArchiveEntry with the specified name, index, and type.
1020 * @param pName Entry name to locate (this is used as the database key)
1021 * @param index Entry index to locate (in case of multiple entries)
1022 * @param type Entry must have this type (@see SkyArchiveTypeCode)
1024 * Returns a pointer to the entry or NULL if no matching entry could be located.
1026 const SkyArchiveEntry* SkyArchive::_FindEntry(const char* pName,
1028 SkyArchiveTypeCode eType) const
1031 // Find the range of entries in the mmap with the key matching /name/
1033 std::pair< SkyMMapConstIter, SkyMMapConstIter > b = _dataTable.equal_range((char*)pName);
1035 unsigned int count = 0;
1036 for (SkyMMapConstIter i = b.first; (i != b.second) && (count <= index); ++i)
1039 // The entry's type and index must match...
1041 const SkyArchiveEntry* pEntry = (*i).second;
1042 if (pEntry->type == eType)
1049 // only increment the count when the type matches
1057 //.---------------------------------------------------------------------------.
1058 //| Function : SkyArchive::_CopyDataTable |
1060 //.---------------------------------------------------------------------------.
1061 void SkyArchive::_CopyDataTable( const SkyArchiveMMap& src)
1063 SkyMMapConstIter iter;
1065 for (iter = src.begin(); iter != src.end(); iter++)
1067 const SkyArchiveEntry* pSrcEntry = (*iter).second;
1068 const char* pSrcName = (*iter).first;
1070 if (ARCHIVE_TYPE == pSrcEntry->type)
1072 SkyArchive* pSrcArchive = (SkyArchive*)pSrcEntry->pData;
1073 AddArchive(*pSrcArchive);
1077 SkyArchiveEntry* pNewEntry = new SkyArchiveEntry;
1078 pNewEntry->type = pSrcEntry->type;
1079 pNewEntry->iDataSize = pSrcEntry->iDataSize;
1080 pNewEntry->pData = new unsigned char[pNewEntry->iDataSize];
1081 ::memcpy( pNewEntry->pData, pSrcEntry->pData, pNewEntry->iDataSize);
1083 char* pName = new char[::strlen(pSrcName)+1];
1084 ::strcpy( pName, pSrcName );
1085 _dataTable.insert(std::make_pair(pName, pNewEntry));
1090 //------------------------------------------------------------------------------
1091 // Function : SkyArchive::_Save
1093 //------------------------------------------------------------------------------
1095 * @fn SkyArchive::_Save(FILE* pDestFile) const
1096 * @brief Saves data to a file (possibly recursively in the case of subarchives).
1098 SKYRESULT SkyArchive::_Save(FILE* pDestFile) const
1100 // fill out a record for this archive & write it
1101 SkyArchiveFileEntry me;
1102 me.type = ARCHIVE_TYPE;
1103 ::strncpy( me.pName, _pName, 32);
1104 me.iDataSize = _dataTable.size();
1106 size_t iNumItemsWritten = fwrite((const void*)&me, sizeof(SkyArchiveFileEntry), 1, pDestFile);
1108 if (1 > iNumItemsWritten)
1109 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Save(): failed to write Archive header.");
1111 SkyMMapConstIter iter;
1112 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
1114 // fill out a record for each item in _dataTable & write it
1115 const SkyArchiveEntry* pEntry = (*iter).second;
1116 switch(pEntry->type)
1120 ((SkyArchive*)(pEntry->pData))->_Save(pDestFile);
1126 SkyArchiveFileEntry item;
1127 item.type = pEntry->type;
1128 ::strncpy( item.pName, (*iter).first, 32);
1129 item.iDataSize = pEntry->iDataSize;
1131 iNumItemsWritten = fwrite((const void*)&item, sizeof(SkyArchiveFileEntry), 1, pDestFile);
1132 if (1 > iNumItemsWritten)
1133 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Save(): failed to write Archive Entry header.");
1134 iNumItemsWritten = fwrite((const void*)pEntry->pData, pEntry->iDataSize, 1, pDestFile);
1135 if (1 > iNumItemsWritten)
1136 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Save(): failed to write Archive Entry data.");
1141 return SKYRESULT_OK;
1145 //------------------------------------------------------------------------------
1146 // Function : SkyArchive::_Load
1148 //------------------------------------------------------------------------------
1150 * @fn SkyArchive::_Load( FILE* pSrcFile)
1151 * @brief Loads data from a file (possibly recursively in the case of subarchives).
1153 SKYRESULT SkyArchive::_Load( FILE* pSrcFile)
1155 // first make sure the file is open and readable.
1157 // load the first record
1158 SkyArchiveFileEntry thisItem;
1159 size_t iNumItemsRead = fread((void*)&thisItem, sizeof(SkyArchiveFileEntry), 1, pSrcFile);
1160 if (1 > iNumItemsRead)
1161 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read Archive header.");
1163 _pName = new char[::strlen(thisItem.pName)+1];
1164 ::strcpy( _pName, thisItem.pName);
1166 for (unsigned int iNumItems = 0; iNumItems < thisItem.iDataSize; ++iNumItems)
1168 SkyArchiveFileEntry embeddedItem;
1169 long iFileLoc = ftell(pSrcFile); // store location before the read
1170 iNumItemsRead = fread((void*)&embeddedItem, sizeof(SkyArchiveFileEntry), 1, pSrcFile);
1171 if (1 > iNumItemsRead)
1172 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read embedded archive item.");
1174 switch( embeddedItem.type)
1178 if (0 != fseek(pSrcFile, iFileLoc, SEEK_SET))
1179 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to set the file position.");
1180 SkyArchive newArchive;
1181 newArchive._Load(pSrcFile); // recursively load the subarchive
1182 AddArchive(newArchive); // add the loaded archive to the database in memory.
1187 void* pData = new unsigned char[embeddedItem.iDataSize];
1188 iNumItemsRead = fread((void*)pData, embeddedItem.iDataSize, 1, pSrcFile);
1189 if (1 > iNumItemsRead)
1190 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read item data.");
1191 AddData( embeddedItem.pName,
1192 (SkyArchiveTypeCode)embeddedItem.type,
1194 embeddedItem.iDataSize);
1200 return SKYRESULT_OK;