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.
25 #include "SkyArchive.hpp"
29 struct SkyArchiveEntry
31 SkyArchiveEntry() : type(0), pData(NULL), iDataSize(0) {}
34 unsigned int iDataSize;
37 struct SkyArchiveFileEntry
39 SkyArchiveFileEntry() : type(0), iDataSize(0) {}
42 unsigned int iDataSize;
46 //------------------------------------------------------------------------------
47 // Function : SkyArchive::SkyArchive
49 //------------------------------------------------------------------------------
51 * @fn SkyArchive::SkyArchive()
52 * @brief Default constructor. Creates an empty, unnamed archive. |
54 SkyArchive::SkyArchive()
60 //------------------------------------------------------------------------------
61 // Function : SkyArchive::SkyArchive
63 //------------------------------------------------------------------------------
65 * @fn SkyArchive::SkyArchive(const char* pName)
66 * @brief Constructor. Creates an empty, named archive.
68 SkyArchive::SkyArchive(const char* pName)
70 _pName = new char[::strlen(pName)+1];
71 ::strcpy( _pName, pName);
75 //.---------------------------------------------------------------------------.
76 //| Function : SkyArchive::SkyArchive |
78 //.---------------------------------------------------------------------------.
80 //------------------------------------------------------------------------------
81 // Function : SkyArchive::SkyArchive
83 //------------------------------------------------------------------------------
85 * @fn SkyArchive::SkyArchive(const SkyArchive& src)
86 * @brief Copy constructor. Deep-copies the contents of one archive to another.
88 SkyArchive::SkyArchive(const SkyArchive& src)
90 _pName = new char[::strlen(src._pName)+1];
91 ::strcpy( _pName, src._pName);
93 _CopyDataTable( src._dataTable);
96 //------------------------------------------------------------------------------
97 // Function : SkyArchive::~SkyArchive
99 //------------------------------------------------------------------------------
101 * @fn SkyArchive::~SkyArchive()
104 SkyArchive::~SkyArchive()
107 SAFE_DELETE_ARRAY(_pName);
111 //.---------------------------------------------------------------------------.
112 //| Function : SkyArchive::operator= |
114 //.---------------------------------------------------------------------------.
116 //------------------------------------------------------------------------------
117 // Function : SkyArchive::operator=
119 //------------------------------------------------------------------------------
121 * @fn SkyArchive::operator=( const SkyArchive& src)
122 * @brief @todo Deep-copies the contents of one archive to another.
124 SkyArchive& SkyArchive::operator=( const SkyArchive& src)
129 SAFE_DELETE_ARRAY(_pName);
130 _pName = new char[::strlen(src._pName)+1];
131 ::strcpy( _pName, src.GetName());
133 _CopyDataTable( src._dataTable);
140 //=============================================================================
141 // Adding Content to SkyArchive
142 //=============================================================================
144 //------------------------------------------------------------------------------
145 // Function : SkyArchive::AddData
147 //------------------------------------------------------------------------------
149 * @fn SkyArchive::AddData(const char* pName,
150 SkyArchiveTypeCode eType,
152 unsigned int iNumBytes,
153 unsigned int iNumItems)
154 * @brief Adds a new data field to the archive.
156 * Makes a copy of the data, stores it in a SkyArchiveEntry, and adds it to the
157 * database. All specialized functions for the base types are implemented using
161 * @param name Field name. This is used as the key for the database entry.
162 * @param type Data type of the field.
163 * @param pData Pointer to the data to be added to the archive.
164 * @param iNumBytes Size of each individual item in the data
165 * @param iNumItems Number of items to copy
167 SKYRESULT SkyArchive::AddData(const char* pName,
168 SkyArchiveTypeCode eType,
170 unsigned int iNumBytes,
171 unsigned int iNumItems /* = 1 */)
173 // fill out a new archive entry with the supplied data
174 SkyArchiveEntry* pNewEntry = new SkyArchiveEntry;
175 pNewEntry->type = eType;
176 pNewEntry->iDataSize = iNumBytes * iNumItems;
178 if (eType != ARCHIVE_TYPE)
180 pNewEntry->pData = new unsigned char[pNewEntry->iDataSize];
181 ::memcpy(pNewEntry->pData, pData, pNewEntry->iDataSize);
185 pNewEntry->pData = (unsigned char*)pData;
188 char* pInternalName = new char[::strlen(pName)+1];
189 ::strcpy( pInternalName, pName);
190 _dataTable.insert(std::make_pair(pInternalName, pNewEntry));
196 //-----------------------------------------------------------------------------
197 // SkyArchive :: AddBool( const char* pName, bool aBool)
198 // SkyArchive :: AddInt8( const char* pName, Int8 anInt8)
199 // SkyArchive :: AddInt16( const char* pName, Int16 anInt16)
200 // SkyArchive :: AddInt32( const char* pName, Int32 anInt32)
202 //-----------------------------------------------------------------------------
204 // Specialized functions for the most common base types
206 //-----------------------------------------------------------------------------
209 //------------------------------------------------------------------------------
210 // Function : SkyArchive::AddBool
212 //------------------------------------------------------------------------------
214 * @fn SkyArchive::AddBool(const char* pName, bool aBool)
215 * @brief Adds a named bool to the archive.
217 SKYRESULT SkyArchive::AddBool(const char* pName, bool aBool)
219 return AddData( pName, BOOL_TYPE, &aBool, sizeof(bool));
222 //------------------------------------------------------------------------------
223 // Function : SkyArchive::AddInt8
225 //------------------------------------------------------------------------------
227 * @fn SkyArchive::AddInt8(const char* pName, char anInt8)
228 * @brief Adds a named 8-bit integer to the archive.
230 SKYRESULT SkyArchive::AddInt8(const char* pName, char anInt8)
232 return AddData( pName, INT8_TYPE, &anInt8, sizeof(char));
235 //------------------------------------------------------------------------------
236 // Function : SkyArchive::AddInt16
238 //------------------------------------------------------------------------------
240 * @fn SkyArchive::AddInt16(const char* pName, short anInt16)
241 * @brief Adds a named 16-bit integer to the archive.
243 SKYRESULT SkyArchive::AddInt16(const char* pName, short anInt16)
245 return AddData( pName, INT16_TYPE, &anInt16, sizeof(short));
248 //------------------------------------------------------------------------------
249 // Function : SkyArchive::AddInt32
251 //------------------------------------------------------------------------------
253 * @fn SkyArchive::AddInt32(const char* pName, int anInt32)
254 * @brief Adds a named 32-bit integer to the archive.
256 SKYRESULT SkyArchive::AddInt32(const char* pName, int anInt32)
258 return AddData( pName, INT32_TYPE, &anInt32, sizeof(int));
261 //------------------------------------------------------------------------------
262 // Function : SkyArchive::AddUInt8
264 //------------------------------------------------------------------------------
266 * @fn SkyArchive::AddUInt8(const char* pName, unsigned char anUInt8)
267 * @brief Adds a named unsigned 8-bit integer to the archive.
269 SKYRESULT SkyArchive::AddUInt8(const char* pName, unsigned char anUInt8)
271 return AddData( pName, UINT8_TYPE, &anUInt8, sizeof(unsigned char));
274 //------------------------------------------------------------------------------
275 // Function : SkyArchive::AddUInt16
277 //------------------------------------------------------------------------------
279 * @fn SkyArchive::AddUInt16(const char* pName, unsigned short anUInt16)
280 * @brief Adds a named unsigned 16-bit integer to the archive.
282 SKYRESULT SkyArchive::AddUInt16(const char* pName, unsigned short anUInt16)
284 return AddData( pName, UINT16_TYPE, &anUInt16, sizeof(unsigned short));
287 //------------------------------------------------------------------------------
288 // Function : SkyArchive::AddUInt32
290 //------------------------------------------------------------------------------
292 * @fn SkyArchive::AddUInt32(const char* pName, unsigned int anUInt32)
293 * @brief Adds a named unsigned 32-bit integer to the archive.
295 SKYRESULT SkyArchive::AddUInt32(const char* pName, unsigned int anUInt32)
297 return AddData( pName, UINT32_TYPE, &anUInt32, sizeof(unsigned int));
300 //------------------------------------------------------------------------------
301 // Function : SkyArchive::AddFloat32
303 //------------------------------------------------------------------------------
305 * @fn SkyArchive::AddFloat32(const char* pName, float aFloat32)
306 * @brief Adds a named 32-bit real number to the archive.
308 SKYRESULT SkyArchive::AddFloat32(const char* pName, float aFloat32)
310 return AddData( pName, FLOAT32_TYPE, &aFloat32, sizeof(float));
313 //------------------------------------------------------------------------------
314 // Function : SkyArchive::AddFloat64
316 //------------------------------------------------------------------------------
318 * @fn SkyArchive::AddFloat64(const char* pName, double aFloat64)
319 * @brief Adds a named 64-bit real number to the archive.
321 SKYRESULT SkyArchive::AddFloat64(const char* pName, double aFloat64)
323 return AddData( pName, FLOAT64_TYPE, &aFloat64, sizeof(double));
326 //------------------------------------------------------------------------------
327 // Function : SkyArchive::AddString
329 //------------------------------------------------------------------------------
331 * @fn SkyArchive::AddString(const char* pName, const char* pString)
332 * @brief Adds a named string to the archive.
334 SKYRESULT SkyArchive::AddString(const char* pName, const char* pString)
336 return AddData( pName, STRING_TYPE, pString, ::strlen(pString)+1);
339 //------------------------------------------------------------------------------
340 // Function : SkyArchive::AddArchive
342 //------------------------------------------------------------------------------
344 * @fn SkyArchive::AddArchive(const SkyArchive& anArchive)
345 * @brief Adds a subarchive to this archive.
347 * This method allows hierarchical data structures to be stored in an archive.
349 SKYRESULT SkyArchive::AddArchive(const SkyArchive& anArchive)
351 SkyArchive* pCopy = new SkyArchive(anArchive);
352 return AddData( pCopy->GetName(), ARCHIVE_TYPE, pCopy, sizeof(SkyArchive));
355 //-----------------------------------------------------------------------------
356 // Adding Vector types
357 //-----------------------------------------------------------------------------
359 //------------------------------------------------------------------------------
360 // Function : SkyArchive::AddVec2f
362 //------------------------------------------------------------------------------
364 * @fn SkyArchive::AddVec2f(const char* pName, const Vec2f& aVec2f)
365 * @brief Adds a 2-component 32-bit real number vector to the archive.
367 SKYRESULT SkyArchive::AddVec2f(const char* pName, const Vec2f& aVec2f)
369 return AddData( pName, VEC2F_TYPE, &aVec2f, sizeof(Vec2f));
372 //------------------------------------------------------------------------------
373 // Function : SkyArchive::AddVec3f
375 //------------------------------------------------------------------------------
377 * @fn SkyArchive::AddVec3f(const char* pName, const Vec3f& aVec3f)
378 * @brief Adds a 3-component 32-bit real number vector to the archive.
380 SKYRESULT SkyArchive::AddVec3f(const char* pName, const Vec3f& aVec3f)
382 return AddData( pName, VEC3F_TYPE, &aVec3f, sizeof(Vec3f));
385 //------------------------------------------------------------------------------
386 // Function : SkyArchive::AddVec4f
388 //------------------------------------------------------------------------------
390 * @fn SkyArchive::AddVec4f(const char* pName, const Vec4f& aVec4f)
391 * @brief Adds a 4-component 32-bit real number vector to the archive.
393 SKYRESULT SkyArchive::AddVec4f(const char* pName, const Vec4f& aVec4f)
395 return AddData( pName, VEC4F_TYPE, &aVec4f, sizeof(Vec4f));
398 //=============================================================================
399 // Retrieving Content from SkyArchive
400 //=============================================================================
402 //------------------------------------------------------------------------------
403 // Function : SkyArchive::FindData
405 //------------------------------------------------------------------------------
407 * @fn SkyArchive::FindData(const char* pName,
408 SkyArchiveTypeCode eType,
410 unsigned int* pNumBytes,
411 unsigned int index) const
412 * @brief Retrieves datafield from _dataTable.
415 * @param name The field name. used as the key for the multimap entry.
416 * @param type Data type of the field.
417 * @param pData Pointer to the returned data.
418 * @param pNumBytes Returns the size of the field entry returned.
419 * @param index Which item of the given \a name to locate.
421 SKYRESULT SkyArchive::FindData(const char* pName,
422 SkyArchiveTypeCode eType,
424 unsigned int* pNumBytes,
425 unsigned int index /* = 0 */) const
427 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, eType);
432 *pData = new unsigned char[pEntry->iDataSize];
433 ::memcpy( ((void*)*pData), pEntry->pData, pEntry->iDataSize);
438 *pNumBytes = pEntry->iDataSize;
443 return SKYRESULT_FAIL;
447 //-----------------------------------------------------------------------------
448 // SkyArchive :: FindBool( const char* pName, bool* aBool)
449 // SkyArchive :: FindInt8( const char* pName, Int8* anInt8)
450 // SkyArchive :: FindInt16( const char* pName, Int16* anInt16)
451 // SkyArchive :: FindInt32( const char* pName, Int32* anInt32)
453 //-----------------------------------------------------------------------------
455 // specialized function for the most common base types
457 //-----------------------------------------------------------------------------
459 //------------------------------------------------------------------------------
460 // Function : SkyArchive::FindBool
462 //------------------------------------------------------------------------------
464 * @fn SkyArchive::FindBool(const char* pName, bool* pBool, unsigned int index) const
465 * @brief Finds a named bool in the archive.
467 SKYRESULT SkyArchive::FindBool(const char* pName, bool* pBool, unsigned int index) const
469 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, BOOL_TYPE);
472 bool* pData = (bool*)(pEntry->pData);
476 return SKYRESULT_FAIL;
479 //------------------------------------------------------------------------------
480 // Function : SkyArchive::FindInt8
482 //------------------------------------------------------------------------------
484 * @fn SkyArchive::FindInt8(const char* pName, char* pInt8, unsigned int index) const
485 * @brief Finds a named 8-bit integer in the archive.
487 SKYRESULT SkyArchive::FindInt8(const char* pName, char* pInt8, unsigned int index) const
489 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT8_TYPE);
492 char* pData = (char*)(pEntry->pData);
496 return SKYRESULT_FAIL;
499 //------------------------------------------------------------------------------
500 // Function : SkyArchive::FindInt16
502 //------------------------------------------------------------------------------
504 * @fn SkyArchive::FindInt16(const char* pName, short* pInt16, unsigned int index) const
505 * @brief Finds a named 16-bit integer in the archive.
507 SKYRESULT SkyArchive::FindInt16(const char* pName, short* pInt16, unsigned int index) const
509 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT16_TYPE);
512 unsigned short* pData = (unsigned short*)(pEntry->pData);
516 return SKYRESULT_FAIL;
519 //------------------------------------------------------------------------------
520 // Function : SkyArchive::FindInt32
522 //------------------------------------------------------------------------------
524 * @fn SkyArchive::FindInt32(const char* pName, int* pInt32, unsigned int index) const
525 * @brief Finds a named 32-bit integer in the archive.
527 SKYRESULT SkyArchive::FindInt32(const char* pName, int* pInt32, unsigned int index) const
529 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, INT32_TYPE);
532 unsigned int* pData = (unsigned int*)(pEntry->pData);
536 return SKYRESULT_FAIL;
539 //------------------------------------------------------------------------------
540 // Function : SkyArchive::FindUInt8
542 //------------------------------------------------------------------------------
544 * @fn SkyArchive::FindUInt8(const char* pName, unsigned char* pUInt8, unsigned int index) const
545 * @brief Finds a named unsigned 8-bit integer in the archive.
547 SKYRESULT SkyArchive::FindUInt8(const char* pName, unsigned char* pUInt8, unsigned int index) const
549 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, UINT8_TYPE);
552 unsigned char* pData = (unsigned char*)(pEntry->pData);
556 return SKYRESULT_FAIL;
559 //------------------------------------------------------------------------------
560 // Function : SkyArchive::FindUInt16
562 //------------------------------------------------------------------------------
564 * @fn SkyArchive::FindUInt16(const char* pName, unsigned short* pUInt16, unsigned int index) const
565 * @brief Finds a named unsigned 16-bit integer in the archive.
567 SKYRESULT SkyArchive::FindUInt16(const char* pName, unsigned short* pUInt16, unsigned int index) const
569 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, UINT16_TYPE);
572 unsigned short* pData = (unsigned short*)(pEntry->pData);
576 return SKYRESULT_FAIL;
579 //------------------------------------------------------------------------------
580 // Function : SkyArchive::FindUInt32
582 //------------------------------------------------------------------------------
584 * @fn SkyArchive::FindUInt32(const char* pName, unsigned int* pUInt32, unsigned int index) const
585 * @brief Finds a named unsigned 32-bit integer in the archive.
587 SKYRESULT SkyArchive::FindUInt32(const char* pName, unsigned int* pUInt32, unsigned int index) const
589 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, UINT32_TYPE);
592 unsigned int* pData = (unsigned int*)(pEntry->pData);
596 return SKYRESULT_FAIL;
599 //------------------------------------------------------------------------------
600 // Function : SkyArchive::FindFloat32
602 //------------------------------------------------------------------------------
604 * @fn SkyArchive::FindFloat32(const char* pName, float* pFloat32, unsigned int index) const
605 * @brief Finds a named 32-bit real number in the archive.
607 SKYRESULT SkyArchive::FindFloat32(const char* pName, float* pFloat32, unsigned int index) const
609 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, FLOAT32_TYPE);
612 float* pData = (float*)(pEntry->pData);
616 return SKYRESULT_FAIL;
619 //------------------------------------------------------------------------------
620 // Function : SkyArchive::FindFloat64
622 //------------------------------------------------------------------------------
624 * @fn SkyArchive::FindFloat64(const char* pName, double* pFloat64, unsigned int index) const
625 * @brief Finds a named 64-bit real number in the archive.
627 SKYRESULT SkyArchive::FindFloat64(const char* pName, double* pFloat64, unsigned int index) const
629 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, FLOAT64_TYPE);
632 double* pData = (double*)(pEntry->pData);
636 return SKYRESULT_FAIL;
639 //------------------------------------------------------------------------------
640 // Function : SkyArchive::FindString
642 //------------------------------------------------------------------------------
644 * @fn SkyArchive::FindString(const char* pName, char** const pString, unsigned int index) const
645 * @brief Finds a named string in the archive.
647 SKYRESULT SkyArchive::FindString(const char* pName, char** const pString, unsigned int index) const
649 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, STRING_TYPE);
652 char* pData = (char*)(pEntry->pData);
653 *pString = new char[pEntry->iDataSize];
654 ::strcpy((char*)*pString, pData);
657 return SKYRESULT_FAIL;
660 //------------------------------------------------------------------------------
661 // Function : SkyArchive::FindArchive
663 //------------------------------------------------------------------------------
665 * @fn SkyArchive::FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index) const
666 * @brief Finds a named sub-archive in the archive.
668 SKYRESULT SkyArchive::FindArchive(const char* pName, SkyArchive* pArchive, unsigned int index) const
670 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, ARCHIVE_TYPE);
673 SkyArchive* pData = (SkyArchive*)(pEntry->pData);
677 return SKYRESULT_FAIL;
680 //------------------------------------------------------------------------------
681 // Function : SkyArchive::FindVec2f
683 //------------------------------------------------------------------------------
685 * @fn SkyArchive::FindVec2f(const char* pName, Vec2f* pVec2f, unsigned int index) const
686 * @brief Finds a 2-component 32-bit real number vector in the archive.
688 SKYRESULT SkyArchive::FindVec2f(const char* pName, Vec2f* pVec2f, unsigned int index) const
690 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, VEC2F_TYPE);
693 Vec2f* pData = (Vec2f*)(pEntry->pData);
697 return SKYRESULT_FAIL;
700 //------------------------------------------------------------------------------
701 // Function : SkyArchive::FindVec3f
703 //------------------------------------------------------------------------------
705 * @fn SkyArchive::FindVec3f(const char* pName, Vec3f* pVec3f, unsigned int index) const
706 * @brief Finds a 3-component 32-bit real number vector in the archive.
708 SKYRESULT SkyArchive::FindVec3f(const char* pName, Vec3f* pVec3f, unsigned int index) const
710 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, VEC3F_TYPE);
713 Vec3f* pData = (Vec3f*)(pEntry->pData);
717 return SKYRESULT_FAIL;
720 //------------------------------------------------------------------------------
721 // Function : SkyArchive::FindVec4f
723 //------------------------------------------------------------------------------
725 * @fn SkyArchive::FindVec4f(const char* pName, Vec4f* pVec4f, unsigned int index) const
726 * @brief Finds a 4-component 32-bit real number vector in the archive.
728 SKYRESULT SkyArchive::FindVec4f(const char* pName, Vec4f* pVec4f, unsigned int index) const
730 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, VEC4F_TYPE);
733 Vec4f* pData = (Vec4f*)(pEntry->pData);
737 return SKYRESULT_FAIL;
740 //------------------------------------------------------------------------------
741 // Function : SkyArchive::AccessArchive
743 //------------------------------------------------------------------------------
745 * @fn SkyArchive::AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index) const
746 * @brief Accesses a named sub-archive in an archive directly.
748 * Note: The data are not copied!
750 SKYRESULT SkyArchive::AccessArchive(const char* pName, SkyArchive** pArchive, unsigned int index) const
752 const SkyArchiveEntry* pEntry = _FindEntry(pName, index, ARCHIVE_TYPE);
755 SkyArchive* pData = (SkyArchive*)(pEntry->pData);
759 return SKYRESULT_FAIL;
763 //------------------------------------------------------------------------------
764 // Function : SkyArchive::GetInfo
766 //------------------------------------------------------------------------------
768 * @fn SkyArchive::GetInfo(const char* pName, SkyArchiveTypeCode eType, unsigned int* pNumFound) const
769 * @brief Computes the number of fields that contain the given name and type.
772 * @param pName Field name to search for.
773 * @param eType Field type to search for.
774 * @param pNumFound Returns the number of fields that contain given name and type.
776 SKYRESULT SkyArchive::GetInfo(const char* pName,
777 SkyArchiveTypeCode eType,
778 unsigned int* pNumFound) const
781 // Find the range of entries in the mmap with the key matching pName
783 std::pair<SkyMMapConstIter, SkyMMapConstIter> b = _dataTable.equal_range((char*)pName);
785 unsigned int count = 0;
786 for ( SkyMMapConstIter i = b.first; i != b.second; ++i )
789 // The entry's type must match...
791 const SkyArchiveEntry* pEntry = (*i).second;
792 if (pEntry->type == eType || ANY_TYPE == eType)
794 // only increment the count when the type matches
805 return SKYRESULT_FAIL;
811 //------------------------------------------------------------------------------
812 // Function : SkyArchive::GetInfo
814 //------------------------------------------------------------------------------
816 * @fn SkyArchive::GetInfo(unsigned int iNameIndex, char** pNameFound, SkyArchiveTypeCode* pTypeCode, unsigned int* pNumFound)
817 * @brief Returns information about the key at the specified index.
820 * @param nameIndex Key index to look up.
821 * @param pNameFound Key name is returned here.
822 * @param pTypeCode Key type is returned here.
823 * @param pNumFound Number of fields held under key name is returned here.
825 SKYRESULT SkyArchive::GetInfo(unsigned int iNameIndex,
827 SkyArchiveTypeCode* pTypeCode,
828 unsigned int* pNumFound)
830 assert( pNameFound != NULL);
833 return SKYRESULT_FAIL;
835 unsigned int iCurrentKeyIndex = 0;
836 SkyMMapConstIter iter;
837 const char* pLastKey = "";
839 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
841 const char* pKey = (*iter).first;
842 if (::strcmp( pLastKey, pKey))
844 if (iCurrentKeyIndex == iNameIndex)
846 *pNameFound = new char[::strlen(pKey) + 1];
847 ::strcpy(*pNameFound, pKey);
851 const SkyArchiveEntry* pEntry = (*iter).second;
852 *pTypeCode = (SkyArchiveTypeCode)pEntry->type;
857 return GetInfo( *pNameFound, *pTypeCode, pNumFound);
866 return SKYRESULT_FAIL;
870 //------------------------------------------------------------------------------
871 // Function : SkyArchive::GetNumUniqueNames
873 //------------------------------------------------------------------------------
875 * @fn SkyArchive::GetNumUniqueNames() const
876 * @brief Computes the number of unique key names in _dataTable.
878 unsigned int SkyArchive::GetNumUniqueNames() const
884 unsigned int iNumKeys = 0;
885 SkyMMapConstIter iter;
886 const char* pLastKey = "";
888 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
890 const char* pKey = (*iter).first;
891 if (::strcmp( pLastKey, pKey))
901 //=============================================================================
902 // Removing Contents of SkyArchive
903 //=============================================================================
905 //------------------------------------------------------------------------------
906 // Function : SkyArchive::MakeEmpty
908 //------------------------------------------------------------------------------
910 * @fn SkyArchive::MakeEmpty()
911 * @brief Remove all the contents of the database.
913 SKYRESULT SkyArchive::MakeEmpty()
917 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
919 SkyArchiveEntry* pEntry = (*iter).second;
920 char* pName = (*iter).first;
921 SAFE_DELETE_ARRAY(pName);
923 if (ARCHIVE_TYPE == pEntry->type)
925 SkyArchive* pArchive = (SkyArchive*)(pEntry->pData);
926 SAFE_DELETE(pArchive);
930 SAFE_DELETE_ARRAY(pEntry->pData);
940 //------------------------------------------------------------------------------
941 // Function : SkyArchive::IsEmpty
943 //------------------------------------------------------------------------------
945 * @fn SkyArchive::IsEmpty() const
946 * @brief returns true if the archive is empty, false if it contains any data.
948 bool SkyArchive::IsEmpty() const
950 return (0 == _dataTable.size());
954 //------------------------------------------------------------------------------
955 // Function : SkyArchive::Load
957 //------------------------------------------------------------------------------
959 * @fn SkyArchive::Load(const char* pFileName)
960 * @brief Load the contents of a SkyArchive from file storage.
962 SKYRESULT SkyArchive::Load(const char* pFileName)
965 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::Load(): file name is NULL.");
967 FILE* pSrcFile = NULL;
970 sprintf(buf,"SkyArchive::Load(%s)",pFileName);
972 if (NULL == (pSrcFile = fopen(pFileName, "rb"))) // file opened successfully
974 SkyTrace("Error: SkyArchive::Load(): failed to open file for reading.");
975 return SKYRESULT_FAIL;
978 SKYRESULT retVal = _Load(pSrcFile);
985 //------------------------------------------------------------------------------
986 // Function : SkyArchive::Commit
988 //------------------------------------------------------------------------------
990 * @fn SkyArchive::Save(const char* pFilename) const
991 * @brief Commit Contents of SkyArchive to file storage.
993 SKYRESULT SkyArchive::Save(const char* pFileName) const
996 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::Save(): file name is NULL.");
998 FILE* pDestFile = NULL;
1000 if (NULL == (pDestFile = fopen(pFileName, "wb"))) // file opened successfully
1001 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::Save(): failed to open file for writing.");
1003 SKYRESULT retVal = _Save(pDestFile);
1007 FAIL_RETURN(retVal);
1008 return SKYRESULT_OK;
1012 //=============================================================================
1013 // Private helper functions
1014 //=============================================================================
1016 //------------------------------------------------------------------------------
1017 // Function : SkyArchive::_FindEntry
1019 //------------------------------------------------------------------------------
1021 * @fn SkyArchive::_FindEntry(const char* pName, unsigned int index, SkyArchiveTypeCode eType) const
1022 * @brief Locates and returns the SkyArchiveEntry with the specified name, index, and type.
1025 * @param pName Entry name to locate (this is used as the database key)
1026 * @param index Entry index to locate (in case of multiple entries)
1027 * @param type Entry must have this type (@see SkyArchiveTypeCode)
1029 * Returns a pointer to the entry or NULL if no matching entry could be located.
1031 const SkyArchiveEntry* SkyArchive::_FindEntry(const char* pName,
1033 SkyArchiveTypeCode eType) const
1036 // Find the range of entries in the mmap with the key matching /name/
1038 std::pair< SkyMMapConstIter, SkyMMapConstIter > b = _dataTable.equal_range((char*)pName);
1040 unsigned int count = 0;
1041 for (SkyMMapConstIter i = b.first; (i != b.second) && (count <= index); ++i)
1044 // The entry's type and index must match...
1046 const SkyArchiveEntry* pEntry = (*i).second;
1047 if (pEntry->type == eType)
1054 // only increment the count when the type matches
1062 //.---------------------------------------------------------------------------.
1063 //| Function : SkyArchive::_CopyDataTable |
1065 //.---------------------------------------------------------------------------.
1066 void SkyArchive::_CopyDataTable( const SkyArchiveMMap& src)
1068 SkyMMapConstIter iter;
1070 for (iter = src.begin(); iter != src.end(); iter++)
1072 const SkyArchiveEntry* pSrcEntry = (*iter).second;
1073 const char* pSrcName = (*iter).first;
1075 if (ARCHIVE_TYPE == pSrcEntry->type)
1077 SkyArchive* pSrcArchive = (SkyArchive*)pSrcEntry->pData;
1078 AddArchive(*pSrcArchive);
1082 SkyArchiveEntry* pNewEntry = new SkyArchiveEntry;
1083 pNewEntry->type = pSrcEntry->type;
1084 pNewEntry->iDataSize = pSrcEntry->iDataSize;
1085 pNewEntry->pData = new unsigned char[pNewEntry->iDataSize];
1086 ::memcpy( pNewEntry->pData, pSrcEntry->pData, pNewEntry->iDataSize);
1088 char* pName = new char[::strlen(pSrcName)+1];
1089 ::strcpy( pName, pSrcName );
1090 _dataTable.insert(std::make_pair(pName, pNewEntry));
1095 //------------------------------------------------------------------------------
1096 // Function : SkyArchive::_Save
1098 //------------------------------------------------------------------------------
1100 * @fn SkyArchive::_Save(FILE* pDestFile) const
1101 * @brief Saves data to a file (possibly recursively in the case of subarchives).
1103 SKYRESULT SkyArchive::_Save(FILE* pDestFile) const
1105 // fill out a record for this archive & write it
1106 SkyArchiveFileEntry me;
1107 me.type = ARCHIVE_TYPE;
1108 ::strncpy( me.pName, _pName, 32);
1109 me.iDataSize = _dataTable.size();
1111 size_t iNumItemsWritten = fwrite((const void*)&me, sizeof(SkyArchiveFileEntry), 1, pDestFile);
1113 if (1 > iNumItemsWritten)
1114 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Save(): failed to write Archive header.");
1116 SkyMMapConstIter iter;
1117 for (iter = _dataTable.begin(); iter != _dataTable.end(); iter++)
1119 // fill out a record for each item in _dataTable & write it
1120 const SkyArchiveEntry* pEntry = (*iter).second;
1121 switch(pEntry->type)
1125 ((SkyArchive*)(pEntry->pData))->_Save(pDestFile);
1131 SkyArchiveFileEntry item;
1132 item.type = pEntry->type;
1133 ::strncpy( item.pName, (*iter).first, 32);
1134 item.iDataSize = pEntry->iDataSize;
1136 iNumItemsWritten = fwrite((const void*)&item, sizeof(SkyArchiveFileEntry), 1, pDestFile);
1137 if (1 > iNumItemsWritten)
1138 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Save(): failed to write Archive Entry header.");
1139 iNumItemsWritten = fwrite((const void*)pEntry->pData, pEntry->iDataSize, 1, pDestFile);
1140 if (1 > iNumItemsWritten)
1141 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Save(): failed to write Archive Entry data.");
1146 return SKYRESULT_OK;
1150 //------------------------------------------------------------------------------
1151 // Function : SkyArchive::_Load
1153 //------------------------------------------------------------------------------
1155 * @fn SkyArchive::_Load( FILE* pSrcFile)
1156 * @brief Loads data from a file (possibly recursively in the case of subarchives).
1158 SKYRESULT SkyArchive::_Load( FILE* pSrcFile)
1160 // first make sure the file is open and readable.
1162 // load the first record
1163 SkyArchiveFileEntry thisItem;
1164 size_t iNumItemsRead = fread((void*)&thisItem, sizeof(SkyArchiveFileEntry), 1, pSrcFile);
1166 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read Archive header.");
1168 _ulEndianSwap(&thisItem.iDataSize);
1170 _pName = new char[::strlen(thisItem.pName)+1];
1171 ::strcpy( _pName, thisItem.pName);
1173 for (unsigned int iNumItems = 0; iNumItems < thisItem.iDataSize; ++iNumItems)
1175 SkyArchiveFileEntry embeddedItem;
1176 long iFileLoc = ftell(pSrcFile); // store location before the read
1177 iNumItemsRead = fread((void*)&embeddedItem, sizeof(SkyArchiveFileEntry), 1, pSrcFile);
1178 if (1 > iNumItemsRead)
1179 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read embedded archive item.");
1181 _ulEndianSwap(&embeddedItem.iDataSize);
1184 switch( embeddedItem.type)
1188 if (0 != fseek(pSrcFile, iFileLoc, SEEK_SET))
1189 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to set the file position.");
1190 SkyArchive newArchive;
1191 newArchive._Load(pSrcFile); // recursively load the subarchive
1192 AddArchive(newArchive); // add the loaded archive to the database in memory.
1197 unsigned char* pData = new unsigned char[embeddedItem.iDataSize];
1198 iNumItemsRead = fread((void*)pData, embeddedItem.iDataSize, 1, pSrcFile);
1199 if (1 > iNumItemsRead)
1200 FAIL_RETURN_MSG(SKYRESULT_FAIL, "Error: SkyArchive::_Load(): failed to read item data.");
1201 AddData( embeddedItem.pName,
1202 (SkyArchiveTypeCode)embeddedItem.type,
1204 embeddedItem.iDataSize);
1210 return SKYRESULT_OK;