[mapguide-commits] r7097 - in trunk/MgDev: Common/CoordinateSystem Common/Geometry/CoordinateSystem Server/src/UnitTesting
svn_mapguide at osgeo.org
svn_mapguide at osgeo.org
Mon Oct 8 14:27:08 PDT 2012
Author: baertelchen
Date: 2012-10-08 14:27:08 -0700 (Mon, 08 Oct 2012)
New Revision: 7097
Modified:
trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h
trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h
trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h
trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h
trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h
trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h
trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp
trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h
trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h
trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp
trunk/MgDev/Common/CoordinateSystem/CriticalSection.h
trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h
trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h
trunk/MgDev/Common/CoordinateSystem/MentorUtil.h
trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h
trunk/MgDev/Common/CoordinateSystem/namestruct.h
trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h
trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp
trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h
Log:
First drop of the RFC 127 implementation
This is the first drop of changes to implement RFC 127 "Change Coordinate System API (MgGeometry) to adopt changes proposed by CS-Map RFC6"
In this first submission, the following main changes are contained:
1) Add the necessary API to the [MgCoordinateSystemCatalog] class:
GetDefaultUserDictionaryDir
SetUserDictionaryDir
GetUserDictionaryDir
1) Change the CCoordinateSystemCategory and CCoordinateSystemCategoryDictionary class to use the CS-Map API instead of
its own implementation to read/write the category information.
2) Changes all generic dictionary code that would call into the CS_[...]rd() functions to use the new CS_[...]rdAll() functions provided by
CS-Map.
3) Unit tests updates:
I have added some new unit tests to the TestCoordinateSystem.h/cpp module.
Those include full reading of the dictionaries as well as some update tests with & without
having a path set for user-defined dictionaries.
At the moment, it's not yet possible to initialize the 'user dictionary dir' from the serverconfig.ini file.
All changes reviewed by Hugues
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -278,19 +278,21 @@
//Sets the complete path to the directory where the dictionaries are
//located. This method can be invoked only when not
-//currently connected to a dictionary database. This method does not
-//perform any validation on the specified dictionary path. Instead,
-//full validation is performed by the OpenDictionaries() method.
-//Throws an exception MgCoordinateSystemCatalogIsOpenException if already connected to a
-//dictionary database
-//
-void CCoordinateSystemCatalog::SetDictionaryDir(CREFSTRING sDirPath)
+//currently connected to a dictionary database. This method just verifies that
+//the dictionary path exists, and, if appropriate, whether a file named Coordsys.CSD could be found-
+//Full validation is performed later on by the OpenDictionaries() method.
+//Throws [MgFileIoException] if the targeted directory is invalid and/or cannot be accessed in the
+//in the mode indicated by [dirWriteAccess]
+
+STRING CCoordinateSystemCatalog::SetDictionaryDir(CREFSTRING sDirPath, bool dirWriteAccess, int (*CsMapDirFunc)(const char *pszDirectoryPath))
{
- MG_TRY()
+ if (NULL == CsMapDirFunc)
+ throw new MgNullArgumentException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
if (sDirPath.empty())
{
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
+ CsMapDirFunc("");
+ return L"";
}
#ifdef _WIN32
@@ -302,14 +304,14 @@
wchar_t szDir[_MAX_DIR] = {0};
wchar_t szFname[_MAX_FNAME] = {0};
wchar_t szExt[_MAX_EXT] = {0};
- _tsplitpath(sDirPath.c_str(), szDrive, szDir, szFname, szExt);
+
+ //make sure, we don't have any '/' in the string that CS-Map could stumble over
+ STRING sPathCopy = sDirPath;
+ std::replace(sPathCopy.begin(), sPathCopy.end(), L'/', L'\\');
+
+ _tsplitpath(sPathCopy.c_str(), szDrive, szDir, szFname, szExt);
if ((_tcslen(szFname) > 0) || (_tcslen(szExt) > 0))
{
- //ABA: don't understand: if a filename or an extension has been found,
- //we concatenate the filename to the directory + then the extension;
- //Then, we call makepath() what will give us a full path information incl.
- //the file name;
- //
//Nope, not properly terminated, need to fix it.
assert(_tcslen(szDir) + _tcslen(szFname) + _tcslen(szExt) < _MAX_DIR);
_tcscat(szDir, szFname);
@@ -337,22 +339,36 @@
szPath, //path to directory
true, //must exist
true, //must be a directory
- false, //must be writable?
+ dirWriteAccess, //must be writable?
&reason))
{
ThrowFileError(L"MgCoordinateSystemCatalog.SetDictionaryDir", szPath, reason);
}
- m_sDir = szPath;
- m_libraryStatus = lsInitializationFailed;
-
- //initializes Mentor
- char* pszPath=Convert_Wide_To_Ascii(szPath);
- CriticalClass.Enter();
- CS_altdr(pszPath);
- CriticalClass.Leave();
+ //initializes CS-Map's target directory function with the new path
+ SmartCriticalClass csmapLock;
+ char* pszPath = Convert_Wide_To_Ascii(szPath);
+ int csmapResult = CsMapDirFunc(pszPath);
delete[] pszPath;
+ //CS-Map return -1 if for cs_altdr() the Coordsys.CSD file couldn't be found; 0 otherwise
+
+ if (csmapResult)
+ throw new MgFileIoException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
+
+ return szPath;
+}
+
+void CCoordinateSystemCatalog::SetDictionaryDir(CREFSTRING sDirPath)
+{
+ MG_TRY()
+
+ if (sDirPath.empty())
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCatalog.SetDictionaryDir", __LINE__, __WFILE__, NULL, L"", NULL);
+
+ m_libraryStatus = lsInitializationFailed;
+ m_sDir = this->SetDictionaryDir(sDirPath, false, CS_altdr);
+
//now need to validate the dictionary files
//an reinitialize their internal data
STRING sCs=m_pCsDict->GetFileName();
@@ -376,6 +392,67 @@
MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetDictionaryDir")
}
+STRING CCoordinateSystemCatalog::GetDefaultUserDictionaryDir()
+{
+ STRING defaultUserDir;
+
+#ifdef _WIN32
+
+ //let the [MENTOR_USER_DICTIONARY_PATH] environment variable override the
+ //the default path - which on Windows systems is the "(user-)Local app data path\Autodesk\User Geospatial Coordinate Systems"
+
+ // Check to see if the environment variable is set
+ const TCHAR* szPathVar = _tgetenv(_T(MENTOR_USER_DICTIONARY_PATH));
+ bool variableDefined = (szPathVar && L'\0' != *szPathVar);
+
+ if(!variableDefined)
+ {
+ TCHAR szPath[MAX_PATH] = { L'\0' };
+ if(TRUE == SHGetSpecialFolderPath(NULL, szPath, CSIDL_LOCAL_APPDATA, FALSE))
+ {
+ defaultUserDir = szPath;
+ defaultUserDir += _T("\\Autodesk\\User Geospatial Coordinate Systems"); //NOXLATE
+ }
+ }
+
+ if (!defaultUserDir.empty() && L'\\' != defaultUserDir[defaultUserDir.length() - 1])
+ defaultUserDir.append(L"\\");
+
+#else
+
+ char* szPath = getenv(MENTOR_USER_DICTIONARY_PATH);
+ bool variableDefined = (szPath && L'\0' != *szPath);
+
+ if (variableDefined)
+ {
+ MgUtil::MultiByteToWideChar(string(szPath), defaultUserDir);
+ if(L'/' != defaultUserDir[defaultUserDir.length() - 1])
+ defaultUserDir.append(L"/");
+ }
+
+#endif
+
+ if (defaultUserDir.empty())
+ return L"";
+
+
+ return defaultUserDir.c_str();
+}
+
+void CCoordinateSystemCatalog::SetUserDictionaryDir(CREFSTRING sDirPath)
+{
+ MG_TRY()
+
+ m_sUserDir = this->SetDictionaryDir(sDirPath /* can be empty */, true, CS_usrdr);
+
+ MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetUserDictionaryDir")
+}
+
+STRING CCoordinateSystemCatalog::GetUserDictionaryDir()
+{
+ return m_sUserDir;
+}
+
//cgeck if the files are writable
//The read mode was tracked down when the file names were set up
//if the files were not valif an assertion was thorwn at that time
@@ -500,9 +577,39 @@
m_pGpDict->SetFileName(sGp);
m_pGxDict->SetFileName(sGx);
- m_libraryStatus=lsInitialized;
+ MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetDefaultDictionaryDirAndFileNames")
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCatalog.SetDefaultDictionaryDirAndFileNames")
+ STRING sDefUserDictionaryDir;
+ {
+ MG_TRY()
+
+ //Get the default path where to store the custom CS information
+ //note, that we don't require that to be available for (the server
+ sDefUserDictionaryDir = this->GetDefaultUserDictionaryDir();
+ if (!sDefUserDictionaryDir.empty())
+ {
+ this->SetUserDictionaryDir(sDefUserDictionaryDir);
+ }
+
+ MG_CATCH_AND_RELEASE()
+
+ #ifdef _DEBUG
+ if (NULL != mgException)
+ {
+ _ASSERT(!sDefUserDictionaryDir.empty());
+ //log the fact, that we couldn't set the right user dictionary dir
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("\n(%t) CCoordinateSystemCatalog::SetDefaultDictionaryDirAndFileNames() - The directory to store user defined CS information could not be set using this directory\n%W.\n"),
+ sDefUserDictionaryDir.c_str()));
+ }
+ else if (!sDefUserDictionaryDir.empty())
+ {
+ ACE_DEBUG((LM_DEBUG, ACE_TEXT("\n(%t) CCoordinateSystemCatalog::SetDefaultDictionaryDirAndFileNames() - The directory to store user defined CS information in has been set to \n%W.\n"),
+ sDefUserDictionaryDir.c_str()));
+ }
+ #endif
+ }
+
+ m_libraryStatus = lsInitialized;
}
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCatalog.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -41,6 +41,10 @@
virtual bool AreDictionaryFilesWritable();
virtual STRING GetDictionaryDir();
+ virtual STRING GetDefaultUserDictionaryDir();
+ virtual void SetUserDictionaryDir(CREFSTRING sDirPath);
+ virtual STRING GetUserDictionaryDir();
+
virtual void SetProtectionMode(INT16 nMode);
virtual INT16 GetProtectionMode();
virtual MgCoordinateSystemCategoryDictionary* GetCategoryDictionary();
@@ -76,6 +80,7 @@
protected:
//Data members
STRING m_sDir;
+ STRING m_sUserDir;
Ptr<CCoordinateSystemDictionary> m_pCsDict;
Ptr<CCoordinateSystemDatumDictionary> m_pDtDict;
@@ -90,6 +95,8 @@
//Unimplemented stuff
CCoordinateSystemCatalog(const CCoordinateSystemCatalog&);
CCoordinateSystemCatalog& operator=(const CCoordinateSystemCatalog&);
+
+ STRING SetDictionaryDir(CREFSTRING sDirPath, bool dirWriteAccess, int (*CsMapDirFunc)(const char *pszDirectoryPath));
};
} // End of namespace
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
+#include <vector>
+
#include "GeometryCommon.h"
#include "CoordSysCommon.h"
@@ -24,302 +26,132 @@
#include "MentorUtil.h" //for IsLegalMentorName
#include <algorithm> //for std::find
+#include "cs_map.h"
+
+using namespace std;
using namespace CSLibrary;
-/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-CCoordinateSystemCategory::CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog)
+extern "C"
{
- m_pCatalog = SAFE_ADDREF(pCatalog);
+ extern int cs_Error;
}
-CCoordinateSystemCategory::~CCoordinateSystemCategory()
+void CCoordinateSystemCategory::CtorInit(CCoordinateSystemCategory* pToInitialize, MgCoordinateSystemCatalog *pCatalog,
+ cs_Ctdef_* pSourceCtDef,
+ bool copyDef)
{
-}
+ if (NULL == pCatalog)
+ throw new MgNullArgumentException(L"MgCoordinateSystemCategory.MgCoordinateSystemCategory()", __LINE__, __WFILE__, NULL, L"", NULL);
-//MgDisposable
-void CCoordinateSystemCategory::Dispose()
-{
- delete this;
-}
+ _ASSERT(NULL != pToInitialize && NULL == pToInitialize->mp_ctDef);
-//Gets the name of the category definition.
-//
-char * CCoordinateSystemCategory::Name()
-{
- return const_cast<char*>(m_categoryName.Name());
-}
-
-//Saves the object to a file. Purpose of the ulMinSize parameter:
-//A category definition is, of necessity, a variable-length record
-//in a file, since it can contain an arbitrary number of coordinate
-//systems. Therefore, when written, it stores the number of coordinate
-//systems which it contains. However, suppose you have a file which
-//consists of a bunch of category definitions, one after the other,
-//and you modify one of them by deleting a single coordinate system
-//from it, thereby making it a bit smaller. In that case, it seems
-//inefficient to have to re-write the entire file, compacting it; better
-//to simply be slightly disk-space-inefficient, write the individual
-//record in situ, and mark it so that the reader knows to skip a bit
-//of space. Thus, a category definition in a disk file actually stores
-//two numbers: how many coordinate systems it actually contains,
-//and how much space (in terms of number of coordinate systems) it
-//occupies in the disk file. The second number will be greater than
-//or equal to the first. The first number will always be supplied by
-//the category definition itself, but the caller needs to supply the
-//second number, which the ulMinSize parameter supplies.
-//
-//This function returns true for success, false for failure. If the
-//ulMinSize parameter is less than the number of coordinate systems
-//in the category, it will be ignored.
-//
-void CCoordinateSystemCategory::SaveToFstream(csFILE *pFile, UINT32 ulMinSize)
-{
- long previousPosition = -1;
- MG_TRY()
-
- UINT32 ulSize = static_cast<UINT32>(m_listCoordinateSystemNames.size());
- if (ulMinSize < ulSize)
+ cs_Ctdef_ *pCategoryCopy = NULL;
+ if (NULL != pSourceCtDef)
{
- ulMinSize = ulSize;
+ if (copyDef)
+ pCategoryCopy = CScpyCategory(pSourceCtDef);
+ else
+ pCategoryCopy = pSourceCtDef;
}
-
- //make sure the file is okay
- if (!pFile || -1==CS_ftell(pFile))
+ else
{
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.SaveToFstream", __LINE__, __WFILE__, NULL, L"", NULL);
+ pCategoryCopy = CSnewCategory(NULL);
}
- if (ferror(pFile))
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.SaveToFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- previousPosition = CS_ftell(pFile); //in case of error
- //We write in this order:
- // 1. Name
- // 2. Size (actual number of coordinate systems)
- // 3. File size (ulMinSize; see description above)
- // 4. The coordinate system names
- // 5. Blank space (if ulMinSize > size)
+ if (NULL == pCategoryCopy)
+ throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.CtorInit", __LINE__, __WFILE__, NULL, L"", NULL);
- //Name.
- CS_fwrite(m_categoryName.Name(), sizeof(char), knMaxCategoryNameLen, pFile);
+ pToInitialize->m_pCatalog = SAFE_ADDREF(pCatalog);
+ pToInitialize->mp_ctDef = pCategoryCopy;
+}
- //Size.
- CS_fwrite(reinterpret_cast<char *>(&ulSize), sizeof(ulSize), 1, pFile);
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemCategory::CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog)
+ : mp_ctDef(NULL)
+{
+ CCoordinateSystemCategory::CtorInit(this, pCatalog);
+}
- //Size in file.
- CS_fwrite(reinterpret_cast<char *>(&ulMinSize), sizeof(ulMinSize), 1, pFile);
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemCategory::CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog, cs_Ctdef_* pCategory)
+ : mp_ctDef(NULL)
+{
+ CCoordinateSystemCategory::CtorInit(this, pCatalog, pCategory, false);
+}
- //Coordinate system names.
- CSystemNameList::const_iterator iter;
- for (iter=m_listCoordinateSystemNames.begin(); iter!=m_listCoordinateSystemNames.end(); ++iter)
- {
- CS_fwrite((*iter).Name(), sizeof(char), cs_KEYNM_DEF, pFile);
- }
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+CCoordinateSystemCategory::CCoordinateSystemCategory(CCoordinateSystemCategory const& toCopyFrom)
+ : mp_ctDef(NULL)
+{
+ CCoordinateSystemCategory::CtorInit(this, toCopyFrom.m_pCatalog, toCopyFrom.mp_ctDef);
+}
- //Blank space, if needed
- assert(ulMinSize >= ulSize);
- UINT32 ulDiff = ulMinSize - ulSize;
- if (ulDiff > 0)
- {
- //I could just pad the blank space with nulls,
- //but I anticipate that it may be handy in the
- //future for diagnostic purposes to be able go into
- //the category dictionary with a binary editor and
- //spot where the blanks are. So I'll pick a distinctive
- //string that's not likely to crop up elsewhere.
- CSystemName dummy(/*NOXLATE*/"fnord");
- for (UINT32 i=0; i<ulDiff; i++)
- {
- CS_fwrite(dummy.Name(), sizeof(char), cs_KEYNM_DEF, pFile);
- }
- }
-
- //We're done! Return success.
- MG_CATCH(L"MgCoordinateSystemCategory.SaveToFstream")
- //If we encountered an error, reset to where we started
- if (0!=ferror(pFile) && -1!=previousPosition)
- {
- CS_fseek(pFile, previousPosition, SEEK_SET);
- throw new MgFileIoException(L"MgCoordinateSystemCategory.SaveToFstream", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemInternalException", NULL);
- }
- MG_THROW()
+CCoordinateSystemCategory& CCoordinateSystemCategory::operator=(const CCoordinateSystemCategory& other)
+{
+ this->CopyFrom(&other);
+ return *this;
}
-//Load the object from a file, returning true for success or false for
-//failure. In case of failure, the object will be cleared to a freshly
-//constructed state, and the stream pointer will be positioned where it was
-//to start with. In case of success, the stream pointer will be positioned
-//just past the end of the object.
-//
-//See description under CCoordinateSystemCategory::SaveToFstream() for details.
-//
-void CCoordinateSystemCategory::LoadFromFstream(csFILE *pFile)
+CCoordinateSystemCategory::~CCoordinateSystemCategory()
{
- long previousPosition = -1;
+ CSrlsCategory(this->mp_ctDef);
+ this->mp_ctDef = NULL;
+}
- MG_TRY()
-
- UINT32 ulDiff;
- CSystemName member;
-
- Clear();
-
- //make sure the stream is okay
- assert(pFile && CS_ftell(pFile)>=0);
- if (!pFile || -1==CS_ftell(pFile))
- {
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- if (ferror(pFile))
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- previousPosition = CS_ftell(pFile); //in case of error
-
- //We read in this order:
- // 1. Name
- // 2. Size (actual number of coordinate systems)
- // 3. File size (ulMinSize; see description under SaveToFstream())
- // 4. The coordinate system names
- // 5. Blank space (if ulMinSize > size)
-
- //Name.
- char tempCharBuffer[knMaxCategoryNameLen] = { '\0' };
- const size_t expectedReadCount = sizeof(tempCharBuffer) / sizeof(char);
- size_t nRead=CS_fread(tempCharBuffer, sizeof(char), expectedReadCount, pFile);
- if (expectedReadCount != nRead)
- {
- _ASSERT(0 == nRead); //otherwise something else is going on here...
-
- //we reached the end of the file
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //copy the category name into our [m_categoryName] TNameStruct
- m_categoryName = tempCharBuffer;
-
- //Size.
- UINT32 ulSize;
- nRead=CS_fread(reinterpret_cast<char *>(&ulSize), sizeof(ulSize), 1, pFile);
- if (1!=nRead)
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //Size in file.
- UINT32 ulMinSize;
- nRead=CS_fread(reinterpret_cast<char *>(&ulMinSize), sizeof(ulMinSize), 1, pFile);
- if (1!=nRead)
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- assert(ulMinSize >= ulSize);
- if (ulMinSize < ulSize)
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- char keyNameBuffer[cs_KEYNM_DEF] = { '\0' };
- const size_t expectedBufferCountRead = sizeof(keyNameBuffer) / sizeof(char);
- //Coordinate system names.
- for (UINT32 i=0; i<ulSize; i++)
- {
- keyNameBuffer[0] = '\0';
- nRead=CS_fread(keyNameBuffer, sizeof(char), expectedBufferCountRead, pFile);
- if (expectedBufferCountRead != nRead)
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- member = keyNameBuffer;
-
- // TODO - WORKAROUND TO SKIP BAD COORDINATE SYSTEMS IN CURRENT DICTIONARIES
- if((strcmp(member.Name(), "IGN63/Hiva") != 0) &&
- (strcmp(member.Name(), "Phoenix") != 0))
- {
- m_listCoordinateSystemNames.push_back(member);
- }
- }
-
- //Blank space, if needed
- assert(ulMinSize >= ulSize);
- ulDiff = ulMinSize - ulSize;
- if (ulDiff > 0)
- {
- CS_fseek(pFile, CS_ftell(pFile) + ulDiff * (sizeof(keyNameBuffer) / sizeof(char)), SEEK_SET);
- }
- if (ferror(pFile))
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //We're done! Return success.
- MG_CATCH(L"MgCoordinateSystemCategory.LoadFromFstream")
- //If we encountered an error, reset to where we started
- if (ferror(pFile) && -1!=previousPosition)
- {
- CS_fseek(pFile, previousPosition, SEEK_SET);
- Clear();
- throw new MgFileIoException(L"MgCoordinateSystemCategory.LoadFromFstream", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemInternalException", NULL);
- }
- MG_THROW()
+//MgDisposable
+void CCoordinateSystemCategory::Dispose()
+{
+ delete this;
}
//Make self into a copy of another category def. Note that the other
//def need only support MgCoordinateSystemCategory-- it doesn't necessarily have
//to be a CCoordinateSystemCategory.
//
-void CCoordinateSystemCategory::CopyFrom(MgCoordinateSystemCategory *pDef)
+void CCoordinateSystemCategory::CopyFrom(CCoordinateSystemCategory const* pDef)
{
- MG_TRY()
-
- assert(NULL != pDef);
+ _ASSERT(NULL != pDef);
if (!pDef)
- {
throw new MgNullArgumentException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- Clear();
+ if (!const_cast<CCoordinateSystemCategory*>(pDef)->IsValid())
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
- //Copy the name
- STRING str = pDef->GetName();
- SetName(str);
+ CCoordinateSystemCategory const* pOtherCategory = dynamic_cast<CCoordinateSystemCategory const*>(pDef);
+ if (NULL == pOtherCategory)
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
- //Get an enumerator
- Ptr<MgCoordinateSystemEnum> pEnum=pDef->GetEnum();
- if (!pEnum)
- {
+ cs_Ctdef_* pCategoryCopy = CScpyCategory(pOtherCategory->mp_ctDef);
+ if (NULL == pCategoryCopy)
throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.CopyFrom", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- //Add the coordinate systems
- for ( ; ; )
- {
- Ptr<MgStringCollection> pCsNameColl=pEnum->NextName(1);
- if (1 != pCsNameColl->GetCount()) break;
- AddCoordinateSystem(pCsNameColl->GetItem(0));
- }
+ MG_TRY()
+
+ this->Clear();
+ this->mp_ctDef = pCategoryCopy;
+
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.CopyFrom")
}
//Gets the name of the def.
STRING CCoordinateSystemCategory::GetName()
{
- STRING sName;
+ STRING categoryName;
+ wchar_t* pszwName = NULL;
MG_TRY()
- wchar_t *pName = Convert_Ascii_To_Wide(m_categoryName.Name());
- if (!pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetName", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- sName=pName;
- delete[] pName;
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetName")
+ pszwName = Convert_Ascii_To_Wide(this->mp_ctDef->ctName);
+ categoryName = pszwName;
- return sName;
+ MG_CATCH(L"MgCoordinateSystemCategory.GetName");
+
+ delete[] pszwName;
+ pszwName = NULL;
+
+ MG_THROW()
+
+ return categoryName;
}
//Sets the name of the def.
@@ -327,23 +159,24 @@
//if the specified name is not legal.
void CCoordinateSystemCategory::SetName(CREFSTRING sName)
{
+ char* pszNewName = NULL;
+
MG_TRY()
- if (!IsLegalName(sName))
- {
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.SetName", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- char *pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
- if (!pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.SetName", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ if (!IsLegalName(sName))
+ {
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.SetName", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
- //assign the name to our internal [TNameStruct]
- m_categoryName = pName;
+ pszNewName = Convert_Wide_To_Ascii(sName.c_str());
+ CS_stncp(this->mp_ctDef->ctName, pszNewName, cs_CATDEF_CATNMSZ);
- delete [] pName;
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.SetName")
+ MG_CATCH(L"MgCoordinateSystemCategory.SetName")
+
+ delete[] pszNewName;
+ pszNewName = NULL;
+
+ MG_THROW()
}
//Gets whether the def is "valid." Validity, in this case, is
@@ -361,7 +194,7 @@
//
bool CCoordinateSystemCategory::IsValid()
{
- return IsLegalName(m_categoryName.Name());
+ return IsLegalName(this->mp_ctDef->ctName);
}
//Private member function which returns whether the specified string
@@ -377,7 +210,7 @@
//String can't be empty or too long
INT32 nLen = static_cast<UINT32>(strlen(kpName));
- return ((nLen > 0) && (nLen < knMaxCategoryNameLen));
+ return ((nLen > 0) && (nLen < cs_CATDEF_CATNMSZ));
}
//Tests the specified string to find out whether it's a legal
@@ -385,7 +218,7 @@
//
bool CCoordinateSystemCategory::IsLegalName(CREFSTRING sName)
{
- return (sName.length() > 0) && (sName.length() < knMaxCategoryNameLen);
+ return (sName.length() > 0) && (sName.length() < cs_CATDEF_CATNMSZ);
}
//Gets whether the def is usable in the context of the given catalog.
@@ -428,63 +261,41 @@
}
//Make sure it's a category def
- MgCoordinateSystemCategory* pCtDef=dynamic_cast<MgCoordinateSystemCategory*>(pDef);
+ CCoordinateSystemCategory* pCtDef=dynamic_cast<CCoordinateSystemCategory*>(pDef);
if (!pCtDef)
{
return false;
}
- //Get enumerators for doing comparison
- Ptr<MgCoordinateSystemEnum> pThis=GetEnum();
- assert(pThis);
- if (!pThis)
+ //our [mp_ctDef]'s must always be set, we don't delete that; unless we ran into a situation where we deleted
+ //the field and then couldn't create a new instance via CSnewCategory
+ if (NULL == pCtDef->mp_ctDef)
{
- return false;
+ _ASSERT(false);
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.IsSameAs", __LINE__, __WFILE__, NULL, L"", NULL);
}
- pThis->Reset();
- Ptr<MgCoordinateSystemEnum> pThat=pCtDef->GetEnum();
- assert(pThat);
- if (!pThat)
+ if (NULL == this->mp_ctDef)
{
- return false;
+ _ASSERT(false);
+ throw new MgInvalidOperationException(L"MgCoordinateSystemCategory.IsSameAs", __LINE__, __WFILE__, NULL, L"", NULL);
}
- pThat->Reset();
- //Start comparing names. Even though the enumerators may
- //allow us to grab many names at one go, we'll do them one
- //at a time. This is to avoid the complication of "what do
- //we do when we ask A for a hundred, and B for a hundred,
- //and they give us different size chunks?" Processing speed
- //isn't much of an issue here, so we'll keep the code simple.
- for ( ; ; )
+ if (this->mp_ctDef->nameCnt != pCtDef->mp_ctDef->nameCnt)
+ return false;
+
+ //now check, whether all the CRS names are the same
+ for(ulong32_t i = 0; i < this->mp_ctDef->nameCnt; ++i)
{
- Ptr<MgStringCollection> pCsNameCollThis=pThis->NextName(1);
- Ptr<MgStringCollection> pCsNameCollThat=pThat->NextName(1);
- if ((0 == pCsNameCollThis->GetCount()) && (0 == pCsNameCollThat->GetCount()))
- {
- //We've reached the end of the list without
- //finding any differences. They're the same.
- return true;
- }
- else if (1==pCsNameCollThis->GetCount() && 1==pCsNameCollThat->GetCount())
- {
- //We got a name from each. Compare them.
- bool bSameName = (0 == _wcsicmp(pCsNameCollThis->GetItem(0).c_str(), pCsNameCollThat->GetItem(0).c_str()));
- if (!bSameName)
- {
- //Different names!
- return false;
- }
- }
- else
- {
- //The lists are of different length! Not the same.
- assert(pCsNameCollThis->GetCount() != pCsNameCollThat->GetCount());
+ char const* pCrsNameThis = (this->mp_ctDef->csNames + i)->csName;
+ char const* pCrsNameOther = (pCtDef->mp_ctDef->csNames + i)->csName;
+
+ if (0 != CS_stricmp(pCrsNameThis, pCrsNameOther))
return false;
- }
- } //for each coordsys name in the category
+ }
+ return true;
+
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.IsSameAs")
return false;
@@ -495,35 +306,22 @@
//
MgCoordinateSystemCategory* CCoordinateSystemCategory::CreateClone()
{
- Ptr<CCoordinateSystemCategory> pNew;
-
MG_TRY()
- //Create a clone object
- pNew = new CCoordinateSystemCategory(m_pCatalog);
+ //Create a clone object
+ return new CCoordinateSystemCategory(*this);
- if (NULL == pNew.p)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.CreateClone", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //Copy the category name
- pNew->m_categoryName = m_categoryName;
-
- //Copy the list of coordinate systems
- pNew->m_listCoordinateSystemNames = m_listCoordinateSystemNames;
-
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.CreateClone")
- //And we're done! Return success.
- return pNew.Detach();
+ _ASSERT(false);
+ return NULL;
}
//Gets the number of coordinate systems listed in the category.
//
UINT32 CCoordinateSystemCategory::GetSize()
{
- return static_cast<UINT32>(m_listCoordinateSystemNames.size());
+ return static_cast<UINT32>(this->GetAllCsNames().size());
}
//Gets an enumerator for listing the names of all the coordinate
@@ -532,43 +330,58 @@
//
MgCoordinateSystemEnum* CCoordinateSystemCategory::GetEnum()
{
- CCoordinateSystemEnumCoordinateSystemInCategory* pNameEnum=NULL;
+ Ptr<CCoordinateSystemEnumCoordinateSystemInCategory> pNameEnum;
MG_TRY()
- pNameEnum=new CCoordinateSystemEnumCoordinateSystemInCategory(m_pCatalog);
- if (!pNameEnum)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- pNameEnum->Initialize(&m_listCoordinateSystemNames);
+
+ pNameEnum=new CCoordinateSystemEnumCoordinateSystemInCategory(m_pCatalog);
+ pNameEnum->Initialize(this->GetAllCsNames());
+
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetEnum")
- return pNameEnum;
+ return pNameEnum.Detach();
}
//-------------------------------------------------------------------------------
+std::vector<STRING>& CCoordinateSystemCategory::GetAllCsNames()
+{
+ MG_TRY()
+
+ if (0 == this->m_listCoordinateSystemNames.size() && this->mp_ctDef->nameCnt > 0)
+ {
+ for(ulong32_t i = 0; i < this->mp_ctDef->nameCnt; ++i)
+ {
+ wchar_t *pszwCsName = Convert_Ascii_To_Wide(this->mp_ctDef->csNames[i].csName);
+ this->m_listCoordinateSystemNames.push_back(pszwCsName);
+ delete[] pszwCsName;
+ }
+ }
+
+ MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetAllCsNames")
+
+ return this->m_listCoordinateSystemNames;
+}
+
+//-------------------------------------------------------------------------------
+void CCoordinateSystemCategory::ClearAllCsNames()
+{
+ this->m_listCoordinateSystemNames.clear();
+}
+
+//-------------------------------------------------------------------------------
MgStringCollection* CCoordinateSystemCategory::GetCoordinateSystems()
{
Ptr<MgStringCollection> pCsColl;
+
MG_TRY()
+ pCsColl = new MgStringCollection;
- pCsColl=new MgStringCollection;
- if (NULL == pCsColl)
+ std::vector<STRING> const& allCsNames = this->GetAllCsNames();
+ for(size_t i = 0; i < allCsNames.size(); ++i)
{
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
+ pCsColl->Add(allCsNames[0]);
}
- CSystemNameList::const_iterator iter;
- for (iter=m_listCoordinateSystemNames.begin(); iter!=m_listCoordinateSystemNames.end(); ++iter)
- {
- wchar_t *pName = Convert_Ascii_To_Wide((*iter).Name()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.GetCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- pCsColl->Add(pName);
- delete[] pName;
- }
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.GetCoordinateSystems")
return pCsColl.Detach();
}
@@ -580,36 +393,52 @@
//
void CCoordinateSystemCategory::AddCoordinateSystem(CREFSTRING sName)
{
+ char *pName = NULL;
+
MG_TRY()
+
+ std::vector<STRING>& allCsNames = this->GetAllCsNames();
+
//Make sure it's a legal name
- char *pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
+ pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
if (NULL == pName)
{
throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
}
+
if (!IsLegalMentorName(pName))
{
- delete [] pName;
throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
}
- //Make a new member out of it
- CSystemName newMember(pName);
- delete [] pName;
-
//See if it's already present
- CSystemNameList::iterator itList=std::find(m_listCoordinateSystemNames.begin(), m_listCoordinateSystemNames.end(), newMember);
- if (itList != m_listCoordinateSystemNames.end())
+ std::vector<STRING>::iterator const& itList = std::find(allCsNames.begin(), allCsNames.end(), sName);
+ if (itList != allCsNames.end())
{
//duplicate!
throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemCategoryDuplicateException", NULL);
}
+ if (CSaddItmNameEx(this->mp_ctDef, pName))
+ {
+ _ASSERT(false); //whatever the problem is here... the name we validated; OOM ? hopefully unlikely
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.AddCoordinateSystem", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemCategoryDuplicateException", NULL);
+ }
+
//Try to insert it in our list
- m_listCoordinateSystemNames.push_back(newMember);
+ allCsNames.push_back(sName);
//Success!
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.AddCoordinateSystem")
+ MG_CATCH(L"MgCoordinateSystemCategory.AddCoordinateSystem")
+
+ delete [] pName;
+ pName = NULL;
+
+ if (NULL != mgException)
+ this->ClearAllCsNames();
+
+ MG_THROW();
+
}
//Removes the specified coordinate system key name from the category.
@@ -619,33 +448,46 @@
//
void CCoordinateSystemCategory::RemoveCoordinateSystem(CREFSTRING sName)
{
+ char *pName = NULL;
+
MG_TRY()
- //Make sure it's a legal name
- char *pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- if (!IsLegalMentorName(pName))
- {
- delete [] pName;
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ std::vector<STRING>& allCsNames = this->GetAllCsNames();
- //Make a member out of it
- CSystemName member(pName);
+ //Make sure it's a legal name
+ pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
+ _ASSERT(NULL != pName); //would throw an exception otherwise
+
+ if (!IsLegalMentorName(pName))
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
+
+ if (CSrmvItmNameEx(this->mp_ctDef, pName))
+ {
+ if (cs_Error != cs_CT_CS_NOT_IN)
+ {
+ //the name should be valid... the only expected error here would be
+ //that we couldn't find the CS in the category
+ _ASSERT(false);
+ allCsNames.clear();
+ }
+
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategory.RemoveCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+
+ //See if it's already present
+ std::vector<STRING>::iterator const& itList = std::find(allCsNames.begin(), allCsNames.end(), sName);
+ if (itList != allCsNames.end())
+ allCsNames.erase(itList);
+
+ MG_CATCH(L"MgCoordinateSystemCategory.RemoveCoordinateSystem")
+
delete [] pName;
+ pName = NULL;
- CSystemNameList::iterator itList=std::find(m_listCoordinateSystemNames.begin(), m_listCoordinateSystemNames.end(), member);
- if (itList != m_listCoordinateSystemNames.end())
- {
- //Found it!
- m_listCoordinateSystemNames.erase(itList);
- }
+ if (NULL != mgException)
+ this->ClearAllCsNames();
- //Return success.
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.RemoveCoordinateSystem")
+ MG_THROW()
}
//Tests whether the category contains the specified coordinate system
@@ -653,40 +495,53 @@
//
bool CCoordinateSystemCategory::HasCoordinateSystem(CREFSTRING sName)
{
- bool bHas=false;
+ bool bHas = false;
+ char *pName = NULL;
+ std::vector<STRING>& allCsNames = this->GetAllCsNames();
+
MG_TRY()
- //Make sure it's a legal name
- char *pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.HasCoordinateSystem", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- if (!IsLegalMentorName(pName))
- {
- delete [] pName;
- return false; //the name is not valid so the category doesn't have it. No assertion since the name might be ok for something else than this coordsys library
- }
- //Make a member out of it
- CSystemName member(pName);
- delete [] pName;
+ //Make sure it's a legal name
+ pName = Convert_Wide_To_Ascii(sName.c_str());
+ if (IsLegalMentorName(pName))
+ {
+ //Try to find it
+ //See if it's already present
+ std::vector<STRING>::iterator const& itList = std::find(allCsNames.begin(), allCsNames.end(), sName);
+ bHas = (itList != allCsNames.end());
+ }
+ //else:
+ //the name is not valid so the category doesn't have it. No assertion since the name might be ok for something else than this coordsys library
- //Try to find it
- CSystemNameList::iterator itList=std::find(m_listCoordinateSystemNames.begin(), m_listCoordinateSystemNames.end(), member);
- bHas=(itList != m_listCoordinateSystemNames.end());
+ MG_CATCH(L"MgCoordinateSystemCategory.HasCoordinateSystem")
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategory.HasCoordinateSystem")
+ delete[] pName;
+ pName = NULL;
+ MG_THROW()
+
return bHas;
}
+cs_Ctdef_ const* CCoordinateSystemCategory::GetCategoryDef() const
+{
+ return this->mp_ctDef;
+}
+
//Clears the object to a freshly constructed state.
//
void CCoordinateSystemCategory::Clear()
{
- m_categoryName = "\0";
- m_listCoordinateSystemNames.clear();
+ this->ClearAllCsNames();
+
+ //create the new empty cs_Ctdef_ instance first
+ struct cs_Ctdef_* pNewCategory = CSnewCategory(NULL);
+ if (NULL == pNewCategory)
+ throw new MgOutOfMemoryException(L"MgCoordinateSystemCategory.MgCoordinateSystemCategory", __LINE__, __WFILE__, NULL, L"", NULL);
+
+ CSrlsCategory(this->mp_ctDef);
+ this->mp_ctDef = pNewCategory;
}
//*****************************************************************************
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategory.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -18,6 +18,8 @@
#ifndef _CCOORDINATESYSTEMCATEGORY_H_
#define _CCOORDINATESYSTEMCATEGORY_H_
+struct cs_Ctdef_;
+
namespace CSLibrary
{
@@ -25,12 +27,13 @@
{
public:
CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog);
+ CCoordinateSystemCategory(MgCoordinateSystemCatalog *pCatalog, cs_Ctdef_* pCategory);
+ CCoordinateSystemCategory(CCoordinateSystemCategory const&);
+ CCoordinateSystemCategory& operator=(const CCoordinateSystemCategory&);
+
virtual ~CCoordinateSystemCategory();
- char *Name();
- void SaveToFstream(csFILE *pFile, UINT32 ulMinSize = 0);
- void LoadFromFstream(csFILE *pFile);
- void CopyFrom(MgCoordinateSystemCategory *pDef);
+ void CopyFrom(CCoordinateSystemCategory const* pDef);
//MgCoordinateSystemCategory
virtual STRING GetName();
@@ -49,24 +52,27 @@
virtual void Clear();
virtual MgCoordinateSystemCatalog* GetCatalog();
+ cs_Ctdef_ const* GetCategoryDef() const;
+
protected:
//MgDisposable
virtual void Dispose();
protected:
//Data members
- CCategoryName m_categoryName;
- CSystemNameList m_listCoordinateSystemNames;
+ std::vector<STRING> m_listCoordinateSystemNames;
Ptr<MgCoordinateSystemCatalog> m_pCatalog;
//Private member functions
static bool IsLegalName(const char *kpName);
private:
- //Unimplemented stuff
- CCoordinateSystemCategory();
- CCoordinateSystemCategory(const CCoordinateSystemCategory&);
- CCoordinateSystemCategory& operator=(const CCoordinateSystemCategory&);
+
+ std::vector<STRING>& GetAllCsNames();
+ void ClearAllCsNames();
+
+ cs_Ctdef_ * mp_ctDef;
+ static void CtorInit(CCoordinateSystemCategory* pToInitialize, MgCoordinateSystemCatalog *pCatalog, cs_Ctdef_* pSourceCtDef = NULL, bool copyDef = true);
};
} // End of namespace
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -89,21 +89,15 @@
CCategoryNameIndexMap& CCoordinateSystemCategoryDictionary::Index()
{
- csFILE* pFile=NULL;
+ _ASSERT(CriticalClass.IsEntered());
MG_TRY()
if (m_bIndexDirty)
{
//if dirty it needs to be regenerated
- SmartCriticalClass critical(true);
- pFile=Open(Read);
- GenerateIndex(pFile);
+ GenerateIndex();
}
MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Index")
- if (pFile)
- {
- CS_fclose(pFile);
- }
MG_THROW()
return m_index;
@@ -111,290 +105,97 @@
CCategoryNameList& CCoordinateSystemCategoryDictionary::List()
{
- csFILE* pFile=NULL;
+ //if dirty it needs to be regenerated
+ SmartCriticalClass critical;
MG_TRY()
- if (m_bIndexDirty)
- {
- //if dirty it needs to be regenerated
- SmartCriticalClass critical(true);
- pFile=Open(Read);
- GenerateIndex(pFile);
- }
+
+ if (m_bIndexDirty)
+ {
+ GenerateIndex();
+ }
+
MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Index")
- if (pFile)
- {
- CS_fclose(pFile);
- }
+
+ if (NULL != mgException)
+ this->InvalidateIndex();
+
MG_THROW()
return m_list;
}
-//Private member function which generates an index from the specified
-//file, which is assumed to point to an open category dictionary file.
-//Returns true for success, false for failure.
-//
-void CCoordinateSystemCategoryDictionary::GenerateIndex(csFILE *pFile)
+void CCoordinateSystemCategoryDictionary::InvalidateIndex()
{
- long previousPos = -1;
- MG_TRY()
+ _ASSERT(CriticalClass.IsEntered());
- assert(pFile && CS_ftell(pFile)>=0);
- previousPos = CS_ftell(pFile);
+ CSrlsCategories(); //our index got of synch; make sure, we force CS-Map to release its in-memory list, too
+ m_bIndexDirty = true;
+
m_index.clear();
m_list.clear();
-
- //Position the stream to the start of the first record
- CS_fseek(pFile, sizeof(klCategoryMagic), SEEK_SET);
- if (ferror(pFile))
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.GenerateIndex", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //Start reading records.
- CCoordinateSystemCategory def(m_pCatalog);
- long curPos=0;
- while (!feof(pFile))
- {
- curPos = CS_ftell(pFile);
- try
- {
- def.LoadFromFstream(pFile);
- }
- catch (MgException *pELoad)
- {
- SAFE_RELEASE(pELoad);
- if (feof(pFile)) break;
- }
- CCategoryName category(def.Name());
- m_index.insert(CCategoryNameIndexPair(category, curPos));
- m_list.push_back(category);
- } //for each def in the file
-
- //Success!
- m_bIndexDirty=false;
- MG_CATCH(L"MgCoordinateSystemCategoryDictionary.GenerateIndex")
- if (mgException != NULL)
- {
- m_index.clear();
- }
- if (-1!=previousPos)
- {
- CS_fseek(pFile, previousPos, SEEK_SET);
- }
- MG_THROW()
}
-
-//Private member function. Rewrites the file. If pDef is NULL,
-//the def specified by kpDefName will simply be omitted; if not NULL,
-//it will be replaced by the def provided.
+//Private member function which generates an index from the specified
+//file, which is assumed to point to an open category dictionary file.
+//Returns true for success, false for failure.
//
-//This function is provided to avoid duplicating code between
-//ModifyCategory() and RemoveCategory().
-//
-void CCoordinateSystemCategoryDictionary::RewriteFile(const char *kpDefName, CCoordinateSystemCategory *pDef)
+void CCoordinateSystemCategoryDictionary::GenerateIndex()
{
- csFILE *pFile=NULL;
- CriticalClass.Enter();
- MG_TRY()
- assert(NULL != kpDefName);
- STRING tempName;
- STRING strPath=GetPath();
+ _ASSERT(CriticalClass.IsEntered());
-#ifdef _WIN32
- //Get a temporary file name
- wchar_t szDrive[_MAX_DRIVE],
- szDir[_MAX_DIR],
- szFname[_MAX_FNAME],
- szExt[_MAX_EXT],
- szPath[_MAX_PATH],
- szTempPath[_MAX_PATH];
- _tsplitpath(strPath.c_str(), szDrive, szDir, szFname, szExt);
- _tmakepath(szPath, szDrive, szDir, NULL, NULL);
+ struct cs_Ctdef_ **pAllCategories = NULL;
+ int categoryCount = 0;
- if (!GetTempFileName(szPath, /*NOXLATE*/L"cat", 0, szTempPath))
- {
- //couldn't open file
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoCategoryDictionaryException", NULL);
- }
- tempName=szTempPath;
-#else
- tempName = MgFileUtil::GenerateTempFileName();
-#endif
+ MG_TRY()
- //Open the file
- csFILE *pTemp;
- char szMode[10];
- GetFileModes(Write, szMode);
- pTemp = fopen( MgUtil::WideCharToMultiByte(tempName).c_str(), szMode );
- if (!pTemp || ferror(pTemp))
- {
- //couldn't open file
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoCategoryDictionaryException", NULL);
- }
+ this->InvalidateIndex();
- //Copy the magic number
- INT32 lMagic;
- GetFileModes(Read, szMode);
- pFile=OpenDictionaryFile(strPath.c_str(), szMode, lMagic, ValidCategoryMagic);
- CS_fwrite(reinterpret_cast<char *>(&lMagic), sizeof(lMagic), 1, pTemp);
-
- //Copy the category definitions across
- CCoordinateSystemCategory curDef(m_pCatalog);
- CCoordinateSystemCategory *pDefToWrite;
- bool bFound = false;
- while (!feof(pFile))
- {
- //Get def from original file
- try
+ categoryCount = CSgetCtDefAll(&pAllCategories);
+ if (categoryCount < 0)
{
- curDef.LoadFromFstream(pFile);
+ _ASSERT(NULL == pAllCategories);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GenerateIndex", __LINE__, __WFILE__, NULL, L"", NULL);
}
- catch (MgException *pELoad)
- {
- SAFE_RELEASE(pELoad);
- if (feof(pFile)) break;
- CS_fclose(pTemp);
- CS_fclose(pFile);
- pFile=NULL;
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- //Is it the one we're replacing?
- pDefToWrite = &curDef;
- if ((!bFound) && (0 == CS_stricmp(kpDefName, curDef.Name())))
+ for(int i = 0; i < categoryCount; ++i)
{
- bFound = true;
- pDefToWrite = pDef;
+ CCategoryName category(pAllCategories[i]->ctName);
+ m_index.insert(CCategoryNameIndexPair(category, i));
+ m_list.push_back(category);
}
- if (NULL != pDefToWrite)
- {
- //Write appropriate def to output file
- bool bOk=true;
- try
- {
- pDefToWrite->SaveToFstream(pTemp);
- }
- catch (MgException *pESave)
- {
- SAFE_RELEASE(pESave);
- bOk=false;
- }
- if (!bOk || ferror(pTemp))
- {
- CS_fclose(pFile);
- pFile=NULL;
- CS_fclose(pTemp);
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- }
- } //until we reach the end of the original file
+ //Success!
+ m_bIndexDirty = false;
- //Okay, we're done. Switch 'em around.
- CS_fclose(pFile);
- pFile=NULL;
- CS_fclose(pTemp);
- char* sz_msPath=Convert_Wide_To_Ascii(strPath.c_str());
- if (!sz_msPath)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.RewriteFile", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- MgFileUtil::DeleteFile( MgUtil::MultiByteToWideChar(sz_msPath) );
- MgFileUtil::RenameFile( tempName, MgUtil::MultiByteToWideChar(sz_msPath) );
+ MG_CATCH(L"MgCoordinateSystemCategoryDictionary.GenerateIndex")
- GetFileModes(Read, szMode);
- pFile=fopen(sz_msPath, szMode);
- delete[] sz_msPath;
-
- //Since the contents of the file presumably changed,
- //we need to re-generate the index.
- GenerateIndex(pFile);
-
- //Return success.
- MG_CATCH(L"MgCoordinateSystemCategoryDictionary.RewriteFile")
- if (pFile)
+ if (NULL != mgException)
{
- CS_fclose(pFile);
- pFile=NULL;
+ this->InvalidateIndex();
}
- CriticalClass.Leave();
- MG_THROW();
-}
-//-----------------------------------------------------------------------------
-csFILE* CCoordinateSystemCategoryDictionary::Open(CsDictionaryOpenMode nOpenMode)
-{
- csFILE* pFile=NULL;
- MG_TRY()
-
- //Make sure they've specified a valid mode
- bool bWriting;
- switch (nOpenMode)
+ //clean up the array we've got from CS-Map, i.e. ...
+ for(int i = 0; i < categoryCount; ++i)
{
- case Read:
- bWriting = false;
- break;
- case Write:
- bWriting = true;
- break;
- default:
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, NULL, L"", NULL);
- break;
+ //...delete each individual entry...
+ CSrlsCategory(pAllCategories[i]);
+ pAllCategories[i] = NULL;
}
- //Validate the existence of the file
- EFileValidity reason;
- STRING strPath=GetPath();
- if (!ValidateFile(
- strPath.c_str(), //the file to validate
- true, //must already exist
- false, //mustn't be a directory,
- bWriting, //whether we need write access
- &reason)) //reason for failure
- {
- switch (reason)
- {
- case kFileInvalidEmptyString:
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, NULL, L"", NULL);
- break;
- case kFileInvalidPath:
- case kFileInvalidDoesNotExist:
- case kFileInvalidIsADir:
- {
- MgStringCollection arguments;
- arguments.Add(strPath);
- throw new MgFileNotFoundException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, &arguments, L"", NULL);
- }
- break;
- case kFileInvalidCantWrite:
- MgStringCollection arguments;
- arguments.Add(strPath);
- throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemDictionaryReadOnlyException", NULL);
- break;
- }
- }
+ //...and finally delete the entire array
+ CS_free(pAllCategories);
+ pAllCategories = NULL;
- //Try to open the dictionary file
- char szMode[10];
- GetFileModes(nOpenMode, szMode);
- INT32 lDummy;
- if (NULL==(pFile=OpenDictionaryFile(strPath.c_str(), szMode, lDummy, ValidCategoryMagic)))
- {
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Open", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ MG_THROW()
- //And we're done! Return success.
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.Open")
- return pFile;
+ return;
}
//-----------------------------------------------------------------------------
STRING CCoordinateSystemCategoryDictionary::GetDefaultFileName()
{
- return L"Category.CSD"; // NOXLATE
+ return WIDEN(cs_CT_NAME);
}
//-----------------------------------------------------------------------------
@@ -437,7 +238,7 @@
//set the index flag to dirty so that it will be generated
//automatically the next time we need it
- m_bIndexDirty=true;
+ this->InvalidateIndex();
m_sFileName=sFileName;
MG_CATCH_AND_THROW(L"MgCoordinateSystemDictionary.SetFileName")
@@ -460,9 +261,13 @@
{
UINT32 nSize=0;
+
MG_TRY()
- //Return the size.
- nSize=static_cast<UINT32>(Index().size());
+
+ SmartCriticalClass csmapLock;
+ //Return the size.
+ nSize=static_cast<UINT32>(Index().size());
+
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.GetSize")
return nSize;
@@ -474,34 +279,23 @@
//def is not the right kind. Otherwise, works like AddCategory().
void CCoordinateSystemCategoryDictionary::Add(MgGuardDisposable *pDefinition)
{
- csFILE* pFile=NULL;
- SmartCriticalClass critical(false);
+ SmartCriticalClass lock;
MG_TRY()
- assert(NULL != pDefinition);
+
+ _ASSERT(NULL != pDefinition);
if (NULL == pDefinition)
{
throw new MgNullArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
}
- MgCoordinateSystemCategory* pCategoryDef=dynamic_cast<MgCoordinateSystemCategory*>(pDefinition);
+ CCoordinateSystemCategory* pCategoryDef=dynamic_cast<CCoordinateSystemCategory*>(pDefinition);
if (!pCategoryDef)
{
throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemMismatchException", NULL);
}
- //Look for it in our index
- STRING str = pCategoryDef->GetName();
- if (str.empty())
- {
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- char *pName = Convert_Wide_To_Ascii(str.c_str()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
- delete [] pName;
+ cs_Ctdef_ const* pCsMapDef = pCategoryDef->GetCategoryDef();
+ CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pCsMapDef->ctName));
//Did we find it?
if (iter != Index().end())
@@ -510,36 +304,31 @@
throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDuplicateException", NULL);
}
- //Is it a valid def?
- bool bValid = pCategoryDef->IsValid();
- if (!bValid)
+ int updateResult = CS_ctupd(pCsMapDef);
+ if (updateResult < 0)
{
- //Invalid def!
+ //the category could not be added to the dictionary
throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Add", __LINE__, __WFILE__, NULL, L"", NULL);
}
- //Build a CCoordinateSystemCategory out of it.
- CCoordinateSystemCategory def(m_pCatalog);
- def.CopyFrom(pCategoryDef);
+ _ASSERT(0 == updateResult); //we must have added it; +1 means "updated"
+ if (0 == updateResult) //otherwise an existing one was updated, i.e. our list should be still in synch, theoretically...
+ {
+ //Add it to our index
+ CCategoryName category(pCsMapDef->ctName);
+ Index().insert(CCategoryNameIndexPair(category, List().size()));
+ List().push_back(category);
+ }
+ else
+ {
+ this->InvalidateIndex();
+ }
- //Try to add it to the end of the list.
- critical.Enter();
- pFile=Open(Write);
- CS_fseek(pFile, 0, SEEK_END);
- long pos = CS_ftell(pFile);
- def.SaveToFstream(pFile);
+ MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Add")
- //Add it to our index
- CCategoryName category(def.Name());
- Index().insert(CCategoryNameIndexPair(category, pos));
- List().push_back(category);
+ if (NULL != mgException)
+ this->InvalidateIndex();
- //Success!
- MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Add")
- if (pFile)
- {
- CS_fclose(pFile);
- }
MG_THROW()
}
@@ -548,14 +337,16 @@
void CCoordinateSystemCategoryDictionary::Remove(CREFSTRING sName)
{
char *pName = NULL;
+ cs_Ctdef_* pCategory = NULL;
+
+ bool bInvalidIndexOnFailure = false;
+
+ SmartCriticalClass critical;
MG_TRY()
//Look for it in our index
- pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ pName = Convert_Wide_To_Ascii(sName.c_str());
+
CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
//Did we find it?
@@ -566,13 +357,56 @@
throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
}
- //Rewrite the file, skipping the specified category.
- //Doing so will re-generate the index as needed,
- //which will invalidate iter.
- RewriteFile(pName);
+ bInvalidIndexOnFailure = true;
+ pCategory = CS_ctdef(pName);
+ if (NULL == pCategory)
+ {
+ MgStringCollection arguments;
+ arguments.Add(sName);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
+
+ int deletionResult = CS_ctdel(pCategory);
+ if (deletionResult)
+ {
+ MgStringCollection arguments;
+ arguments.Add(sName);
+ throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemInternalException", NULL);
+ }
+
+ int updateCategoriesResult = CSupdCategories(NULL);
+ if (updateCategoriesResult)
+ {
+ MgStringCollection arguments;
+ arguments.Add(sName);
+ throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Remove", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemInternalException", NULL);
+ }
+
+ long position = iter->second;
+ CCategoryName const& categoryName = List().at(position);
+ if (0 != CS_stricmp(categoryName.Name(), pName)) //is the category name at the index what we think it is?
+ {
+ _ASSERT(false);
+ this->InvalidateIndex();
+ }
+ else
+ {
+ Index().erase(iter->first);
+ List().erase(List().begin() + position);
+ }
+
MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Remove")
- delete [] pName;
+
+ delete [] pName;
+ pName = NULL;
+
+ CSrlsCategory(pCategory);
+ pCategory = NULL;
+
+ if (bInvalidIndexOnFailure && NULL != mgException)
+ InvalidateIndex();
+
MG_THROW()
}
@@ -582,84 +416,78 @@
//def is not the right kind.
void CCoordinateSystemCategoryDictionary::Modify(MgGuardDisposable *pDefinition)
{
- CCoordinateSystemCategory def(m_pCatalog);
- csFILE* pFile=NULL;
- SmartCriticalClass critical(false);
+ char *pName = NULL;
+ cs_Ctdef_* pCategory = NULL;
+ bool invalidIndexOnFailure = false;
+
+ SmartCriticalClass csmapLock;
MG_TRY()
- assert(NULL != pDefinition);
- if (NULL == pDefinition)
- {
- throw new MgNullArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- MgCoordinateSystemCategory* pCategoryDef=dynamic_cast<MgCoordinateSystemCategory*>(pDefinition);
- if (!pCategoryDef)
- {
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemMismatchException", NULL);
- }
+ _ASSERT(NULL != pDefinition);
+ if (NULL == pDefinition)
+ throw new MgNullArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
- //Look for it in our index
- STRING str = pCategoryDef->GetName();
- if (str.empty())
- {
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- char *pName = Convert_Wide_To_Ascii(str.c_str()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
- delete [] pName;
+ CCoordinateSystemCategory* pCategoryDef=dynamic_cast<CCoordinateSystemCategory*>(pDefinition);
+ if (!pCategoryDef)
+ {
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemMismatchException", NULL);
+ }
- //Did we find it?
- if (iter == Index().end())
- {
- MgStringCollection arguments;
- arguments.Add(str);
- throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
- }
+ //Look for it in our index
+ STRING str = pCategoryDef->GetName();
+ if (str.empty())
+ {
+ throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
+ pName = Convert_Wide_To_Ascii(str.c_str());
- //Make a CCoordinateSystemCategory object out of what we're given
- def.CopyFrom(pCategoryDef);
+ CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
- //If the new definition is smaller than or equal to the existing
- //definition's space in the file, we can do a simple in-place
- //replacement in the file. Otherwise, we'll need to re-write the
- //whole file to make room.
- //
- //Find out how big the existing def is in the file.
- critical.Enter();
- pFile=Open(Write);
- long pos = (*iter).second;
- UINT32 ulFileSize;
- CS_fseek(pFile, pos + knMaxCategoryNameLen + sizeof(UINT32), SEEK_SET);
- size_t nRead=CS_fread(reinterpret_cast<char *>(&ulFileSize), sizeof(ulFileSize), 1, pFile);
- if (1!=nRead)
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ //Did we find it?
+ if (iter == Index().end())
+ {
+ MgStringCollection arguments;
+ arguments.Add(str);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
- //Can we do in-place replacement?
- UINT32 ulSize = def.GetSize();
- if (ulSize <= ulFileSize)
- {
- //Yep.
- CS_fseek(pFile, pos, SEEK_SET);
- def.SaveToFstream(pFile, ulFileSize);
- //Success! We're done.
- CS_fclose(pFile);
- return;
- }
+ invalidIndexOnFailure = true;
+ pCategory = CS_ctdef(pName);
+ if (NULL == pCategory)
+ {
+ MgStringCollection arguments;
+ arguments.Add(str);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
+
+ int updateResult = CS_ctupd(pCategory);
+ if (updateResult < 0)
+ {
+ MgStringCollection arguments;
+ arguments.Add(str);
+ throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Modify", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemInternalException", NULL);
+ }
+
+ _ASSERT(1 == updateResult);
+ if (0 == updateResult)
+ {
+ //an item was added... something went wrong here; invalidate the index so we re-read it next time
+ this->InvalidateIndex();
+ }
+
MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Modify")
- if (pFile)
- {
- CS_fclose(pFile);
- }
- //No, we can't do in-place replacement. We have to re-write the file.
- RewriteFile(def.Name(), &def);
+
+ delete[] pName;
+ pName = NULL;
+
+ CSrlsCategory(pCategory);
+ pCategory = NULL;
+
+ if(invalidIndexOnFailure && NULL != mgException)
+ this->InvalidateIndex();
+
MG_THROW()
}
@@ -673,54 +501,53 @@
MgCoordinateSystemCategory* CCoordinateSystemCategoryDictionary::GetCategory(CREFSTRING sName)
{
Ptr<CCoordinateSystemCategory> pNew;
- csFILE* pFile=NULL;
char *pName = NULL;
- SmartCriticalClass critical(false);
- MG_TRY()
+ cs_Ctdef_* pCategory = NULL;
- //Look for it in our index
- pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
+ bool invalidIndexOnFailure = false;
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ SmartCriticalClass critical;
+ MG_TRY()
- CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
+ //Look for it in our index
+ pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
+ CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
- //Did we find it?
- if (iter == Index().end())
- {
- //Nope.
- MgStringCollection arguments;
- arguments.Add(sName);
- throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
- }
+ //Did we find it?
+ if (iter == Index().end())
+ {
+ //Nope.
+ MgStringCollection arguments;
+ arguments.Add(sName);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
- //Make a new object
- pNew = new CCoordinateSystemCategory(m_pCatalog);
+ invalidIndexOnFailure = true;
- if (NULL == pNew.p)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ cs_Ctdef_* pCategory = CS_ctdef(pName);
+ if (NULL == pCategory)
+ {
+ //Nope.
+ MgStringCollection arguments;
+ arguments.Add(sName);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.GetCategory", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
- //Get the definition out of the file.
- critical.Enter();
- pFile=Open(Read);
- long pos = (*iter).second;
- CS_fseek(pFile, pos, SEEK_SET);
- pNew->LoadFromFstream(pFile);
+ //Make a new object with the [cs_Ctdef_] instance we got
+ pNew = new CCoordinateSystemCategory(m_pCatalog, pCategory);
+ pCategory = NULL; //is now owned by [pNew]
MG_CATCH(L"MgCoordinateSystemCategoryDictionary.GetCategory")
- if (pFile)
- {
- CS_fclose(pFile);
- }
+ delete [] pName;
+ pName = NULL;
- delete [] pName;
+ CSrlsCategory(pCategory);
+ pCategory = NULL;
+ if (NULL != mgException && invalidIndexOnFailure)
+ this->InvalidateIndex();
+
MG_THROW()
return pNew.Detach();
@@ -729,21 +556,26 @@
//Returns whether the set contains a def with the specified name.
bool CCoordinateSystemCategoryDictionary::Has(CREFSTRING sName)
{
- bool bHas=false;
+ char *pName = NULL;
+ bool bHas = false;
MG_TRY()
- //Look in our index
- char *pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
- if (NULL == pName)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Has", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
- delete [] pName;
- bHas=(iter != Index().end());
- MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.Has")
+ //Look in our index
+ pName = Convert_Wide_To_Ascii(sName.c_str()); //need to delete [] pName
+ SmartCriticalClass csmapLock;
+
+ CCategoryNameIndexMap::const_iterator iter = Index().find(CCategoryName(pName));
+ bHas = (iter != Index().end());
+
+ MG_CATCH(L"MgCoordinateSystemCategoryDictionary.Has")
+
+ delete pName;
+ pName = NULL;
+
+ MG_THROW()
+
return bHas;
}
@@ -751,25 +583,19 @@
//Gets an enumerator for all the defs in the set.
MgCoordinateSystemEnum* CCoordinateSystemCategoryDictionary::GetEnum()
{
- MgCoordinateSystemEnum* pEnum=NULL;
+ Ptr<CCoordinateSystemEnumCategory> pNewEnum;
MG_TRY()
//Make an enumerator object
- CCoordinateSystemEnumCategory *pNewEnum=new CCoordinateSystemEnumCategory;
+ pNewEnum = new CCoordinateSystemEnumCategory;
+
//Set it up to use our list
- //const_cast because "this" will not be modified in the process
- MgCoordinateSystemCategoryDictionary* pSet=dynamic_cast<MgCoordinateSystemCategoryDictionary*>(this);
- assert(pSet);
- pNewEnum->Initialize(pSet, &List());
+ pNewEnum->Initialize(this, &List());
- //Now that we have the new object set up, QI it to get the
- //proper interface pointer. This also takes care of reference
- //counting so that Release() will properly free the new object.
- pEnum=static_cast<MgCoordinateSystemEnum*>(pNewEnum);
- assert(pEnum);
MG_CATCH_AND_THROW(L"MgCoordinateSystemCategoryDictionary.GetEnum")
- return pEnum;
+
+ return pNewEnum.Detach();
}
//-----------------------------------------------------------------------------
@@ -784,99 +610,58 @@
//-----------------------------------------------------------------------------
void CCoordinateSystemCategoryDictionary::Rename(CREFSTRING sOldName, CREFSTRING sNewName)
{
- csFILE* pFile=NULL;
+ char *pOldName = NULL;
+ char *pNewName = NULL;
+ cs_Ctdef_* pCategory = NULL;
+ bool invalidIndexOnFailure = false;
+ SmartCriticalClass csmapLock;
+
MG_TRY()
- //Make sure new name is a valid one
- CCoordinateSystemCategory def(this->m_pCatalog);
- bool bLegal = def.IsLegalName(sNewName);
- if (!bLegal)
- {
- MgStringCollection whatArguments;
- whatArguments.Add(sNewName);
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &whatArguments, L"", NULL);
- }
+ //Make sure def with old name is present
+ pOldName = Convert_Wide_To_Ascii(sOldName.c_str());
+ CCategoryName oldCategory(pOldName);
- //Make sure def with old name is present
- char *pName = Convert_Wide_To_Ascii(sOldName.c_str());
- CCategoryName oldCategory(pName);
- delete [] pName;
- CCategoryNameIndexMap::iterator iter = Index().find(oldCategory);
- if (iter == Index().end())
- {
- //nope, not there
- MgStringCollection arguments;
- arguments.Add(sOldName);
- throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
- }
+ CCategoryNameIndexMap::iterator iter = Index().find(oldCategory);
+ if (iter == Index().end())
+ {
+ //nope, not there
+ MgStringCollection arguments;
+ arguments.Add(sOldName);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
- //Make sure def with new name is *not* present
- bool bHas = Has(sNewName);
- if (bHas)
- {
- //there's already a def with that name
- throw new MgInvalidArgumentException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDuplicateException", NULL);
- }
+ invalidIndexOnFailure = true;
+ pCategory = CS_ctdef(pOldName);
+ if (NULL == pCategory)
+ {
+ MgStringCollection arguments;
+ arguments.Add(sOldName);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, &arguments, L"MgCoordinateSystemNotFoundException", NULL);
+ }
- INT32 lMagic;
- char szMode[10];
- GetFileModes(Write, szMode);
- STRING strPath=GetPath();
- pFile=OpenDictionaryFile(strPath.c_str(), szMode, lMagic, ValidCategoryMagic);
+ pNewName = Convert_Wide_To_Ascii(sNewName.c_str());
+ if (CSrplCatNameEx(pOldName, pNewName))
+ throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNotFoundException", NULL);
- //load our previous def, with the old name
- long pos = (*iter).second;
- CS_fseek(pFile, pos, SEEK_SET);
- def.LoadFromFstream(pFile);
+ if (CSupdCategories(NULL))
+ throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNotFoundException", NULL);
- //Change its name
- def.SetName(sNewName);
+ long index = iter->second;
+ Index().erase(iter);
+ Index().insert(std::pair<CCategoryName,long>(CCategoryName(pNewName), index));
- //Find out how big the existing def is in the file.
- UINT32 ulFileSize;
- CS_fseek(pFile, pos + knMaxCategoryNameLen + sizeof(UINT32), SEEK_SET);
- size_t nRead=CS_fread(reinterpret_cast<char *>(&ulFileSize), sizeof(ulFileSize), 1, pFile);
- if (1!=nRead)
- {
- throw new MgFileIoException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"", NULL);
- }
+ MG_CATCH(L"MgCoordinateSystemCategoryDictionary.rename")
- //Overwrite the def
- CS_fseek(pFile, pos, SEEK_SET);
- clearerr(pFile);
- def.SaveToFstream(pFile, ulFileSize);
+ delete[] pOldName;
+ delete[] pNewName;
+ pOldName = NULL;
+ pNewName = NULL;
- //Update our index as appropriate.
- pName = Convert_Wide_To_Ascii(sNewName.c_str());
- CCategoryName newCategory(pName);
- delete [] pName;
- try
- {
- Index().erase(iter);
- Index().insert(CCategoryNameIndexPair(newCategory, pos));
- }
- catch (std::bad_alloc)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemCategoryDictionary.Rename", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- CCategoryNameList::iterator iterList;
- for (iterList = List().begin(); iterList != List().end(); ++iterList)
- {
- if (oldCategory == *iterList)
- {
- *iterList = newCategory;
- break;
- }
- }
+ if (NULL != mgException && invalidIndexOnFailure)
+ this->InvalidateIndex();
- //Success!
- MG_CATCH(L"MgCoordinateSystemCategoryDictionary.rename")
- if (pFile)
- {
- CS_fclose(pFile);
- pFile=NULL;
- }
MG_THROW()
}
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysCategoryDictionary.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -66,9 +66,9 @@
bool m_bIndexDirty;
//Private member functions
- void GenerateIndex(csFILE *pFile);
- void RewriteFile(const char *kpDefName, CCoordinateSystemCategory *pDef=NULL);
- csFILE* Open(CsDictionaryOpenMode nOpenMode);
+ void GenerateIndex();
+ void InvalidateIndex();
+
CCategoryNameIndexMap& Index();
CCategoryNameList& List();
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDatumDictionary.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -683,15 +683,21 @@
DtKey06,
DtDesc06,
CS_dtrd06);
- break;
+ break;
case 7:
case 8:
//Generate summary for version 7 or 8 datum file.
+
+ //close the file before calling into the [read all CS-Map defs] method
+ if (0 != CS_fclose(pFile))
+ throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
+
+ pFile = NULL;
+
m_pmapSystemNameDescription = MentorDictionary::GenerateSystemNameDescriptionMap<cs_Dtdef_>(
- pFile,
DtKey,
DtDesc,
- CS_dtrd);
+ CS_dtdefAll);
break;
default:
assert(0);
@@ -747,7 +753,7 @@
throw new MgInvalidArgumentException(L"CCoordinateSystemDatumDictionary.ReadAllDatums", __LINE__, __WFILE__, NULL, L"", NULL);
//place a lock here - we don't want any interference; what we need is the *current* status of all dictionary files
- SmartCriticalClass dictionaryLock(true);
+ SmartCriticalClass dictionaryLock;
Ptr<MgCoordinateSystemCatalog> catalog = targetDictionary->GetCatalog();
Ptr<MgCoordinateSystemEllipsoidDictionary> ellipsoidDictionary = catalog->GetEllipsoidDictionary();
@@ -763,7 +769,7 @@
//finally, read all "root" coordinate system definitions from the dictionary
return MentorDictionary::ReadAllDefinitions<MgCoordinateSystemDatum, cs_Dtdef_, CCoordinateSystemDatumDictionary>(
datumDictionary,
- CS_dtrd,
+ CS_dtdefAll,
NULL, //no additional processing
&CCoordinateSystemDatumDictionary::GetDatum,
&ellipsoidInfos,
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDictionary.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -356,6 +356,8 @@
//------------------------------------------------------------------------
void CCoordinateSystemDictionary::SetFileName(CREFSTRING sFileName)
{
+ char* szCs = NULL;
+
MG_TRY()
//Make local variables to hold converted strings
@@ -375,22 +377,22 @@
m_sFileName,
L"MgCoordinateSystemDictionary.SetFileName");
+ SmartCriticalClass csMapLock;
+
//Okay, everybody opened all right, so update Mentor's global
//variables appropriately.
- char* szCs=Convert_Wide_To_Ascii(sFileName.c_str()); //ABA: why use sFileName here?
- CriticalClass.Enter();
+ szCs = Convert_Wide_To_Ascii(sFileName.c_str());
CS_csfnm(szCs);
- CriticalClass.Leave();
- delete[] szCs; //ABA: where is that deleted in case of an exception
- if (m_pmapSystemNameDescription)
- {
- m_pmapSystemNameDescription->clear();
- delete m_pmapSystemNameDescription;
- m_pmapSystemNameDescription=NULL;
- }
+ delete m_pmapSystemNameDescription;
+ m_pmapSystemNameDescription = NULL;
- MG_CATCH_AND_THROW(L"MgCoordinateSystemDictionary.SetFileName")
+ MG_CATCH(L"MgCoordinateSystemDictionary.SetFileName")
+
+ delete[] szCs;
+ szCs = NULL;
+
+ MG_THROW()
}
//------------------------------------------------------------------------
@@ -692,7 +694,7 @@
//finally, read all "root" coordinate system definitions from the dictionary
return MentorDictionary::ReadAllDefinitions<MgCoordinateSystem, cs_Csdef_, CCoordinateSystemDictionary>(
csDictionary,
- CS_csrd,
+ CS_csdefAll,
&CCoordinateSystemDictionary::DoCsDefPostReadProcessing,
&CCoordinateSystemDictionary::GetCoordinateSystem,
&datumEllipsoidInfos,
@@ -729,8 +731,7 @@
MG_TRY()
STRING strPath=GetPath();
- pFile=MentorDictionary::Open(m_lMagic, CoordinateSystemValidMagic, strPath.c_str(), Read);
-
+ pFile = MentorDictionary::Open(m_lMagic, CoordinateSystemValidMagic, strPath.c_str(), Read);
const int nVersion = CoordinateSystemVersion(m_lMagic);
assert(nVersion > 0);
@@ -760,11 +761,16 @@
case 7:
case 8:
//Generate summary for version 7 or 8 coordsys file.
+ //close the file before calling into the [read all CS-Map defs] method
+ if (0 != CS_fclose(pFile))
+ throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
+
+ pFile = NULL;
+
m_pmapSystemNameDescription = MentorDictionary::GenerateSystemNameDescriptionMap<cs_Csdef_>(
- pFile,
CsKey,
CsDesc,
- CS_csrd);
+ CS_csdefAll);
break;
default:
assert(0);
@@ -783,11 +789,11 @@
throw new MgOutOfMemoryException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
}
- if (0!=CS_fclose(pFile))
+ if (pFile && 0 != CS_fclose(pFile))
{
throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
}
- pFile=NULL;
+ pFile = NULL;
MG_CATCH(L"MgCoordinateSystemDictionary.GetEnum")
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -323,7 +323,6 @@
dictionaryFile = MentorDictionary::Open(this->dictMagicNumber, definitionAccess->magicNumberCallback, strPath.c_str(), Read);
allDictionaryEntries = MentorDictionary::GenerateSystemNameDescriptionMap<U>(
- dictionaryFile,
definitionAccess->readDefinitionName,
definitionAccess->readDefinitionDescription,
definitionAccess->readAllDefinitions);
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysDictionaryBase.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -42,7 +42,7 @@
void (*FullInitialize)(T*, U*, MgCoordinateSystemCatalog* catalog), //fully initializes the Mg API objects from the CS Map API struct
const char* (*ReadDefinitionName)(const U& definition), //reads the definition's name; the caller has to copy the string's content
const char* (*ReadDefinitionDescription)(const U& definition), //reads the definition's description; the caller must copy the string's content (if not NULL)
- int (*ReadAllDefinitions) (csFILE *strm, U* definition, int*), // reads the entire content of a dictionary file; depends on the current file pointer position
+ int (*ReadAllDefinitions) (U** pDefinition[]), // reads the entire content of a dictionary file(s);
void (*CsMapTargetFileName)(const char *newFileName), //set the target dictionary file name in the CS Map library
CsDictionaryOpenMode (*MagicNumberCallback)(long)) //returns the correct open mode for a dictionary file taking into account the magic number read from the file; passed in as long
:
@@ -73,7 +73,7 @@
void (*fullInitialize)(T*, U*, MgCoordinateSystemCatalog* catalog);
const char* (*readDefinitionName)(const U& definition);
const char* (*readDefinitionDescription)(const U& definition);
- int (*readAllDefinitions) (csFILE *strm, U* definition, int*);
+ int (*readAllDefinitions) (U** pDefinitions[]);
void (*csMapTargetFileName) (const char *newFileName);
CsDictionaryOpenMode (*magicNumberCallback)(long);
};
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEllipsoidDictionary.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -580,16 +580,22 @@
MG_TRY()
STRING strPath=GetPath();
- pFile=MentorDictionary::Open(m_lMagic, EllipsoidValidMagic, strPath.c_str(), Read);
+ pFile = MentorDictionary::Open(m_lMagic, EllipsoidValidMagic, strPath.c_str(), Read);
+ _ASSERT(pFile);
+ //close the file before calling into the [read all CS-Map defs] method
+ if (0 != CS_fclose(pFile))
+ throw new MgFileIoException(L"MgCoordinateSystemDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
+
+ pFile = NULL;
+
//Generate a summary list, if we don't already have one
if (NULL == m_pmapSystemNameDescription)
{
m_pmapSystemNameDescription = MentorDictionary::GenerateSystemNameDescriptionMap<cs_Eldef_>(
- pFile,
ElKey,
ElDesc,
- CS_elrd);
+ CS_eldefAll);
if (NULL == m_pmapSystemNameDescription)
{
throw new MgInvalidArgumentException(L"MgCoordinateSystemEllipsoidDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
@@ -599,16 +605,13 @@
//Make an enumerator object
pNew = new CCoordinateSystemEnumEllipsoid;
- if (NULL == pNew.p)
+ if (pFile && 0 != CS_fclose(pFile))
{
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEllipsoidDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- if (0!=CS_fclose(pFile))
- {
throw new MgFileIoException(L"MgCoordinateSystemEllipsoidDictionary.GetEnum", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemDictionaryCloseFailedException", NULL);
}
- pFile=NULL;
+ pFile = NULL;
+
MG_CATCH(L"MgCoordinateSystemEllipsoidDictionary.GetEnum")
if (pFile)
@@ -638,7 +641,7 @@
return MentorDictionary::ReadAllDefinitions<MgCoordinateSystemEllipsoid, cs_Eldef_, CCoordinateSystemEllipsoidDictionary>(
ellipsoidDictionary,
- CS_elrd,
+ CS_eldefAll,
NULL, //no post processing needed
&CCoordinateSystemEllipsoidDictionary::GetEllipsoid,
NULL, //no additional info needed/used to create an MgCoordinateSystemEllipsoid object
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCategory.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -133,7 +133,6 @@
void CCoordinateSystemEnumCategory::Initialize(
MgCoordinateSystemCategoryDictionary* pDict,
CCategoryNameList *kpCategoryNameList)
-
{
assert(NULL != kpCategoryNameList);
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -15,6 +15,8 @@
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
+#include <vector>
+
#include "GeometryCommon.h"
#include "CoordSysCommon.h"
@@ -23,14 +25,26 @@
#include "MentorUtil.h" //for IsLegalMentorName()
using namespace CSLibrary;
+using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CCoordinateSystemEnumCoordinateSystemInCategory::CCoordinateSystemEnumCoordinateSystemInCategory(MgCoordinateSystemCatalog *pCatalog)
- : m_kpListCoordinateSystemNames(NULL)
{
m_pCatalog = SAFE_ADDREF(pCatalog);
}
+CCoordinateSystemEnumCoordinateSystemInCategory::CCoordinateSystemEnumCoordinateSystemInCategory(CCoordinateSystemEnumCoordinateSystemInCategory const& copyFrom)
+{
+ this->m_pCatalog = SAFE_ADDREF(copyFrom.m_pCatalog.p);
+ this->Initialize(copyFrom.m_csNames);
+
+ for (size_t i=0; i < copyFrom.m_vectFilter.size(); i++)
+ {
+ this->m_vectFilter.push_back(copyFrom.m_vectFilter[i]);
+ SAFE_ADDREF(this->m_vectFilter[i]);
+ }
+}
+
CCoordinateSystemEnumCoordinateSystemInCategory::~CCoordinateSystemEnumCoordinateSystemInCategory()
{
ClearFilter();
@@ -69,14 +83,10 @@
//This function must be called on a freshly-constructed CCoordinateSystemEnumCoordinateSystemInCategory
//object before anything else can be done with it.
//
-void CCoordinateSystemEnumCoordinateSystemInCategory::Initialize(
- const CSystemNameList *kpListCoordinateSystemNames)
-
+void CCoordinateSystemEnumCoordinateSystemInCategory::Initialize(std::vector<STRING> const& allCsNames)
{
- assert(NULL != kpListCoordinateSystemNames);
-
- m_kpListCoordinateSystemNames = kpListCoordinateSystemNames;
- m_iter = m_kpListCoordinateSystemNames->begin();
+ this->m_csNames = allCsNames;
+ this->m_iter = this->m_csNames.begin();
}
//----------------------------------------------------------
@@ -95,14 +105,14 @@
{
throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemEnum.Next", __LINE__, __WFILE__, NULL, L"", NULL);
}
- Ptr<MgCoordinateSystemDictionary> pCsDict=m_pCatalog->GetCoordinateSystemDictionary();
+
+ Ptr<MgCoordinateSystemDictionary> pCsDict = m_pCatalog->GetCoordinateSystemDictionary();
if (!pCsDict)
{
throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystem.Next", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoDictionaryException", NULL);
}
- wchar_t* pstr;
- for (; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
+ for (; m_iter != this->m_csNames.end(); ++m_iter)
{
if (pOutput->GetCount() == ulCount)
{
@@ -110,31 +120,16 @@
return pOutput.Detach();
}
- //get the coordinate system name from the category
- const char *kpName = (*m_iter).Name();
-
- assert(IsLegalMentorName(kpName));
- pstr = Convert_Ascii_To_Wide(kpName);
- if (NULL == pstr)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.Next", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- STRING strCsName(pstr);
- delete[] pstr;
-
//now get the definition from the dictionary
- Ptr<MgGuardDisposable> pCs=pCsDict->Get(strCsName);
- if (!pCs)
- {
- MgStringCollection arguments;
- arguments.Add(strCsName);
- throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemEnum.Next", __LINE__, __WFILE__, &arguments, L"", NULL);
- }
+ Ptr<MgGuardDisposable> pCs = pCsDict->Get(m_iter->c_str());
+ _ASSERT(NULL != pCs);
+
//is it filtered out?
if (IsFilteredOut(pCs))
{
continue;
}
+
pOutput->Add(pCs);
}
@@ -150,36 +145,14 @@
{
Ptr<MgStringCollection> pOutput;
MG_TRY()
- pOutput=new MgStringCollection;
- if (!pOutput)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextName", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- wchar_t* pstr;
- for (; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
- {
- if (pOutput->GetCount() == ulCount)
- {
- //success
- return pOutput.Detach();
- }
- const char *kpName = (*m_iter).Name();
- if (IsFilteredOut(kpName))
+ pOutput=new MgStringCollection;
+ Ptr<MgDisposableCollection> pNextCsObjects = this->Next(ulCount);
+ for(INT32 i = 0; i < pNextCsObjects->GetCount(); ++i)
{
- continue;
+ pOutput->Add(Ptr<MgCoordinateSystem>(dynamic_cast<MgCoordinateSystem*>(pNextCsObjects->GetItem(i)))->GetCsCode());
}
- assert(IsLegalMentorName(kpName));
- pstr = Convert_Ascii_To_Wide(kpName);
- if (NULL == pstr)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextName", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- pOutput->Add(pstr);
- delete[] pstr;
- }
-
MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.NextName")
return pOutput.Detach();
}
@@ -189,61 +162,14 @@
{
Ptr<MgStringCollection> pOutput;
MG_TRY()
- pOutput=new MgStringCollection;
- if (!pOutput)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- if (!m_pCatalog)
- {
- throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- Ptr<MgCoordinateSystemDictionary> pCsDict=m_pCatalog->GetCoordinateSystemDictionary();
- if (!pCsDict)
- {
- throw new MgCoordinateSystemInitializationFailedException(L"MgCoordinateSystem.NextDescription", __LINE__, __WFILE__, NULL, L"MgCoordinateSystemNoDictionaryException", NULL);
- }
- wchar_t* pstr;
- for (; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
- {
- if (pOutput->GetCount() == ulCount)
+ pOutput=new MgStringCollection;
+ Ptr<MgDisposableCollection> pNextCsObjects = this->Next(ulCount);
+ for(INT32 i = 0; i < pNextCsObjects->GetCount(); ++i)
{
- //success
- return pOutput.Detach();
+ pOutput->Add(Ptr<MgCoordinateSystem>(dynamic_cast<MgCoordinateSystem*>(pNextCsObjects->GetItem(i)))->GetDescription());
}
- //get the coordinate system name from the category
- const char *kpName = (*m_iter).Name();
- assert(IsLegalMentorName(kpName));
- pstr = Convert_Ascii_To_Wide(kpName);
- if (NULL == pstr)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- STRING strCsName(pstr);
- delete[] pstr;
-
- //now get the definition from the dictionary
- Ptr<MgGuardDisposable> pCs=pCsDict->Get(strCsName);
- if (!pCs)
- {
- MgStringCollection arguments;
- arguments.Add(strCsName);
- throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemEnum.NextDescription", __LINE__, __WFILE__, &arguments, L"", NULL);
- }
- //is it filtered out?
- if (IsFilteredOut(pCs))
- {
- continue;
- }
- MgCoordinateSystem* pCsDef=dynamic_cast<MgCoordinateSystem*>(pCs.p);
- assert(pCsDef);
- STRING strDescription=pCsDef->GetDescription();
-
- pOutput->Add(strDescription);
- }
-
MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.NextDescription")
return pOutput.Detach();
}
@@ -256,16 +182,16 @@
{
MG_TRY()
UINT32 ulSkipped;
- for (ulSkipped=0; m_iter != m_kpListCoordinateSystemNames->end(); ++m_iter)
+ for (ulSkipped=0; m_iter != m_csNames.end(); ++m_iter)
{
if (ulSkipped == ulSkipCount)
{
//success
return;
}
+
//get the coordinate system name from the category
- const char *kpName = (*m_iter).Name();
- if (IsFilteredOut(kpName))
+ if (IsFilteredOut(m_iter->c_str()))
{
continue;
}
@@ -285,40 +211,13 @@
//
void CCoordinateSystemEnumCoordinateSystemInCategory::Reset()
{
- m_iter = m_kpListCoordinateSystemNames->begin();
+ m_iter = this->m_csNames.begin();
}
//This function evaluates the provided def using the current
//Filter. If there is no Filter, the result will always
//be true.
//
-bool CCoordinateSystemEnumCoordinateSystemInCategory::IsFilteredOut(const char *kpName)
-{
- bool bIsFiltered=false;
-
- MG_TRY()
- assert(NULL != kpName);
- if (!kpName)
- {
- throw new MgNullArgumentException(L"MgCoordinateSystemEnum.IsFilteredOut", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //Get a def from the set for the Filter to work with
- wchar_t* pStr = Convert_Ascii_To_Wide(kpName);
- if (NULL == pStr)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.IsFilteredOut", __LINE__, __WFILE__, NULL, L"", NULL);
- }
- bIsFiltered=IsFilteredOut(pStr);
- delete[] pStr;
- MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.IsFilteredOut")
- return bIsFiltered;
-}
-
-//This function evaluates the provided def using the current
-//Filter. If there is no Filter, the result will always
-//be true.
-//
bool CCoordinateSystemEnumCoordinateSystemInCategory::IsFilteredOut(const wchar_t *kpName)
{
bool bIsFiltered=false;
@@ -398,29 +297,13 @@
//
MgCoordinateSystemEnum* CCoordinateSystemEnumCoordinateSystemInCategory::CreateClone()
{
- Ptr<CCoordinateSystemEnumCoordinateSystemInCategory> pNew;
-
MG_TRY()
- //Make a new object
- pNew = new CCoordinateSystemEnumCoordinateSystemInCategory(m_pCatalog);
+ //Make a new object and return it
+ return new CCoordinateSystemEnumCoordinateSystemInCategory(*this);
- if (NULL == pNew.p)
- {
- throw new MgOutOfMemoryException(L"MgCoordinateSystemEnum.CreateClone", __LINE__, __WFILE__, NULL, L"", NULL);
- }
-
- //Copy it from this one
- pNew->m_iter = m_iter;
- pNew->m_kpListCoordinateSystemNames = m_kpListCoordinateSystemNames;
- for (size_t i=0; i<m_vectFilter.size(); i++)
- {
- pNew->m_vectFilter.push_back(m_vectFilter[i]);
- SAFE_ADDREF(m_vectFilter[i]);
- }
-
MG_CATCH_AND_THROW(L"MgCoordinateSystemEnum.CreateClone")
- //And we're done! Return success.
- return pNew.Detach();
+ _ASSERT(false);
+ return NULL;
}
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysEnumCoordinateSystemInCategory.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -25,9 +25,10 @@
{
public:
CCoordinateSystemEnumCoordinateSystemInCategory(MgCoordinateSystemCatalog *pCatalog);
+ CCoordinateSystemEnumCoordinateSystemInCategory(CCoordinateSystemEnumCoordinateSystemInCategory const& copyFrom);
virtual ~CCoordinateSystemEnumCoordinateSystemInCategory();
- void Initialize(const CSystemNameList *kpListCoordinateSystemNames);
+ void Initialize(std::vector<STRING> const& allCsNames);
virtual MgDisposableCollection* Next(UINT32 ulCount);
virtual void Skip(UINT32 ulSkipCount);
@@ -42,14 +43,13 @@
protected:
bool IsFilteredOut(MgGuardDisposable *pDef);
- bool IsFilteredOut(const char *kpName);
bool IsFilteredOut(const wchar_t *kpName);
void ClearFilter();
protected:
//Data members
- const CSystemNameList *m_kpListCoordinateSystemNames;
- CSystemNameList::const_iterator m_iter;
+ std::vector<STRING> m_csNames;
+ std::vector<STRING>::const_iterator m_iter;
Ptr<MgCoordinateSystemCatalog> m_pCatalog;
std::vector<MgCoordinateSystemFilter*> m_vectFilter;
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -48,8 +48,9 @@
CCoordinateSystemGeodeticPathDictionary::ReadName,
CCoordinateSystemGeodeticPathDictionary::ReadDescription,
- CCoordinateSystemGeodeticPathDictionary::ReadAllGeodeticPaths,
+ CS_gpdefAll,
+
CS_gpfnm,
CCoordinateSystemGeodeticPathDictionary::GetFileOpenMode);
@@ -91,11 +92,6 @@
return CS_gpupd(csPath);
}
-int CCoordinateSystemGeodeticPathDictionary::ReadAllGeodeticPaths(csFILE *file, cs_GeodeticPath_ *gp_def, int* /*unused*/)
-{
- return CS_gprd(file, gp_def);
-}
-
bool CCoordinateSystemGeodeticPathDictionary::SetupCsGeodeticPathStruct(CCoordinateSystemGeodeticPath* mgGeodeticPath, cs_GeodeticPath_& csPath)
{
_ASSERT(NULL != mgGeodeticPath);
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticPathDictionary.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -72,7 +72,6 @@
static const char* ReadDescription(const cs_GeodeticPath_& definition);
static int UpdateGeodeticPath(cs_GeodeticPath_* csPath, int /*unused*/);
- static int ReadAllGeodeticPaths(csFILE *file, cs_GeodeticPath_ *gp_def, int* /*unused*/);
static bool SetupCsGeodeticPathStruct(CCoordinateSystemGeodeticPath* mgGeodeticPath, cs_GeodeticPath_& csPath);
static void FullInitialize(CCoordinateSystemGeodeticPath* mgGeodeticPath, cs_GeodeticPath_* csPath, MgCoordinateSystemCatalog* catalog);
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -48,7 +48,7 @@
CCoordinateSystemGeodeticTransformDefDictionary::ReadName,
CCoordinateSystemGeodeticTransformDefDictionary::ReadDescription,
- CCoordinateSystemGeodeticTransformDefDictionary::ReadAllGeodeticTransformDefs,
+ CS_gxdefAll,
CS_gxfnm,
@@ -200,11 +200,6 @@
return definition.description;
}
-int CCoordinateSystemGeodeticTransformDefDictionary::ReadAllGeodeticTransformDefs(csFILE *file, cs_GeodeticTransform_* csTransformDef, int* /*unused*/)
-{
- return CS_gxrd(file, csTransformDef);
-}
-
CsDictionaryOpenMode CCoordinateSystemGeodeticTransformDefDictionary::GetFileOpenMode(long magicNumberFromFile)
{
if (cs_GXDEF_MAGIC == magicNumberFromFile)
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysGeodeticTransformDefDictionary.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -71,8 +71,6 @@
static const char* ReadName(const cs_GeodeticTransform_& definition);
static const char* ReadDescription(const cs_GeodeticTransform_& definition);
- static int ReadAllGeodeticTransformDefs(csFILE *file, cs_GeodeticTransform_* csTransformDef, int* /*unused*/);
-
static CsDictionaryOpenMode GetFileOpenMode(long magicNumberFromFile);
};
Modified: trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CoordSysUtil.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -38,8 +38,6 @@
namespace CSLibrary
{
-const STRING CategoryFilename = L"Category.CSD"; // NOXLATE
-
const double ZERO_SCALE = 1e-9; //-- unit scale smaller than this is considered zero
const double ZERO_VALUE = 1e-12; //-- value smaller than this is considered zero
}
Modified: trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CriticalSection.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -68,6 +68,19 @@
::LeaveCriticalSection(&CritSect);
}
+#ifdef _DEBUG
+ bool CustomCriticalSection::IsEntered()
+ {
+ if (!::TryEnterCriticalSection(&CritSect))
+ return false;
+
+ bool wasHeld = (CritSect.RecursionCount > 0);
+ ::LeaveCriticalSection(&CritSect);
+
+ return wasHeld;
+ }
+#endif
+
#else //LINUX
CustomCriticalSection::~CustomCriticalSection()
@@ -97,4 +110,11 @@
pthread_mutex_unlock(&CritSect);
}
-#endif //_WIN32
+#ifdef _DEBUG
+ bool CustomCriticalSection::IsEntered()
+ {
+ return true;
+ }
+#endif
+
+#endif //_WIN32 / LINUX
Modified: trunk/MgDev/Common/CoordinateSystem/CriticalSection.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CriticalSection.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CriticalSection.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -31,6 +31,12 @@
void Enter();
void Leave();
+#ifdef _DEBUG
+
+ bool IsEntered();
+
+#endif
+
private:
bool m_bInitialized;
};
Modified: trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/CsmapVersion.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -19,6 +19,7 @@
#define __CSMAP_CONSTANTS__
// Windows and Linux will always use the environment variable
-#define MENTOR_DICTIONARY_PATH "MENTOR_DICTIONARY_PATH" // No translate
+#define MENTOR_DICTIONARY_PATH "MENTOR_DICTIONARY_PATH" // No translate
+#define MENTOR_USER_DICTIONARY_PATH "MENTOR_USER_DICTIONARY_PATH" // No translate
#endif
Modified: trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/MentorDictionary.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -41,6 +41,37 @@
namespace MentorDictionary
{
+ template<class TCsMap, class TContainer >
+ class TContainerPtr : public auto_ptr<TContainer>
+ {
+ public:
+ TContainerPtr()
+ : auto_ptr<TContainer>()
+ {
+ }
+
+ TContainerPtr(TContainer* pContainer)
+ : auto_ptr<TContainer>(pContainer)
+ {
+ }
+
+ ~TContainerPtr()
+ {
+ TContainer* pContainer = auto_ptr<TContainer>::get();
+ if (NULL == pContainer)
+ return;
+
+ for(typename TContainer::iterator iter = pContainer->begin();
+ iter != pContainer->end(); ++iter)
+ {
+ if (NULL != *iter)
+ CS_free(*iter);
+ *iter = NULL;
+ }
+ }
+ };
+
+
void SetFileName(INT32& lMagic, CsDictionaryOpenMode (*ValidMagic)(long), CREFSTRING sDirectory, CREFSTRING sFileName, REFSTRING sFileNameSet, const wchar_t* kpMethodName);
csFILE* Open(INT32& lMagic, CsDictionaryOpenMode (*ValidMagic)(long), const wchar_t* kpPath, CsDictionaryOpenMode nOpenMode);
CsDictionaryOpenMode OpenReadDictionaryOpenCallback(long dictMagicNumber);
@@ -69,7 +100,7 @@
//iterates through all entries return a vector of definitions in the same order as they've been returned by CsMap
//return NULL, if the file couldn't be read successfully
template <class T>
- vector<T>*
+ vector<T*>*
ReadDictionaryEntries(
csFILE *pFile,
int (*CS_Trd)(csFILE*, T *, int *))
@@ -77,12 +108,17 @@
//Scan through the file - add an entry for each definition we find
try
{
- auto_ptr<vector<T> > allDictEntries(new vector<T>);
+ TContainerPtr<T, vector<T*> > allDictEntries;
+ allDictEntries.reset(new vector<T*>);
int nCrypt;
- T def;
+ T* def = NULL;
- while (MentorDictionary::GetNextEntry(pFile, def, nCrypt, CS_Trd))
+ def = (T*) CS_malc(sizeof(T));
+ if (NULL == def)
+ throw new MgOutOfMemoryException(L"MentorDictionary.ReadDictionaryEntries", __LINE__, __WFILE__, NULL, L"", NULL);
+
+ while (MentorDictionary::GetNextEntry(pFile, *def, nCrypt, CS_Trd))
{
allDictEntries->push_back(def);
@@ -104,11 +140,13 @@
//opens a dictionary file for reading and then iterates over all entries and returns them as a vector; the order is the same as returned by CsMap
//before accessing the file, a global lock is placed through an [SmartCriticalClass] object
template <class T>
- vector<T>* ReadDictionaryEntries(
+ vector<T*>* ReadDictionaryEntries(
/*IN*/ MgCoordinateSystemDictionaryBase* targetDictionary,
/*IN*/ int (*CS_Trd)(csFILE*, T *, int *))
{
- auto_ptr<vector<T> > allDefs;
+ typedef vector<T*> CsMapDefPtrVector;
+
+ TContainerPtr<T, CsMapDefPtrVector> allDefs;
csFILE *pFile = NULL;
MG_TRY()
@@ -137,7 +175,7 @@
return allDefs.release();
}
- //Template function which generates a summary from a dictionary
+ //Template function(s) which generates a summary from a dictionary
//file. The caller is responsible for deleting the returned map.
//Function returns NULL if it runs out of memory. Note that this
//is a fairly expensive function, timewise, since it involves
@@ -145,7 +183,42 @@
//a megabyte in size. Template parameter T is a Mentor struct
//(cs_Csdef_ et al).
//
+
template <class T>
+ CSystemNameDescriptionMap*
+ GenerateSystemNameDescriptionMap(
+ vector<T*> const* csMapDefs,
+ const char* (*CS_Tkey)(const T&),
+ const char * (*description)(const T&))
+ {
+ try
+ {
+ //Make a collection to return - we first read all entries from the dictionary file
+ //and use those to fill up the dictionary we're returning
+ auto_ptr<CSystemNameDescriptionMap> pmapSystemNameDescription(new CSystemNameDescriptionMap);
+ for(typename vector<T>::size_type i = 0; i < csMapDefs->size(); ++i)
+ {
+ T* def = csMapDefs->at(i);
+
+ const char* keyName = CS_Tkey(*def);
+ pmapSystemNameDescription->insert(
+ CSystemNameDescriptionPair(
+ CSystemName(keyName),
+ CSystemDescription(description(*def))
+ )
+ );
+ }
+
+ return pmapSystemNameDescription.release();
+ }
+ catch(std::bad_alloc&)
+ {
+ }
+
+ return NULL;
+ }
+
+ template <class T>
CSystemNameDescriptionMap *
GenerateSystemNameDescriptionMap(
csFILE *pFile,
@@ -166,25 +239,11 @@
//Make a collection to return - we first read all entries from the dictionary file
//and use those to fill up the dictionary we're returning
auto_ptr<CSystemNameDescriptionMap> pmapSystemNameDescription(new CSystemNameDescriptionMap);
-
- auto_ptr<vector<T> > allDictEntries(MentorDictionary::ReadDictionaryEntries(pFile, CS_Trd));
+ TContainerPtr<T, vector<T*> > allDictEntries(MentorDictionary::ReadDictionaryEntries(pFile, CS_Trd));
if (NULL == allDictEntries.get())
return NULL;
- for(typename vector<T>::size_type i = 0; i < allDictEntries->size(); i++)
- {
- T& def = allDictEntries->at(i);
-
- const char* keyName = CS_Tkey(def);
- pmapSystemNameDescription->insert(
- CSystemNameDescriptionPair(
- CSystemName(keyName),
- CSystemDescription(description(def))
- )
- );
- }
-
- return pmapSystemNameDescription.release();
+ return GenerateSystemNameDescriptionMap(allDictEntries.get(), CS_Tkey, description);
}
catch(std::bad_alloc&)
{
@@ -193,6 +252,33 @@
return NULL;
}
+ template <class T>
+ CSystemNameDescriptionMap *
+ GenerateSystemNameDescriptionMap(
+ const char* (*CS_Tkey)(const T&),
+ const char * (*description)(const T&),
+ int (*CS_TrdAll)(T **[]))
+ {
+ typedef vector<T*> CsMapDefPtrVector;
+
+ TContainerPtr<T*, CsMapDefPtrVector > definitions;
+ definitions.reset(new vector<T*>);
+
+ T** pAllDefs = NULL;
+ int readStatus = CS_TrdAll(&pAllDefs);
+ if (readStatus < 0)
+ return NULL;
+
+ for(int i = 0; i < readStatus; ++i)
+ definitions->push_back(pAllDefs[i]);
+
+ //free the pointer array only - not the items;
+ //these are now owned by [definitions]
+ CS_free(pAllDefs);
+
+ return GenerateSystemNameDescriptionMap(definitions.get(), CS_Tkey, description);
+ }
+
//Reads all Mg definitions from the dictionary [targetDictionary] and returns them
//in the std::map [definitions], where the code is mapped to the MgDisposable
template <class T>
@@ -264,7 +350,7 @@
template <class T /* The MgCS type [primaryDictionary] contains*/, class U /* The CsMap struct type*/, class V /* The dictionary type that will return items of type T*/>
MgDisposableCollection* ReadAllDefinitions(
/*IN, required*/ V* primaryDictionary, //the primary MgCS dictionary to read the items of type T from
- /*IN, required*/ int (*CS_Trd)(csFILE*, U *, int *), //The file access method as retrieved from CsMap
+ /*IN, required*/ int (*CS_TrdAll)(U **pDefArray[]), //The CsMap method to read all entries
/*IN, optional*/ void (V::*PostProcess)(U*), //A method that's being called with the CsMap definition struct just read from the file
/*IN, required*/ T* (V::*GetMgItem)(const U*, const std::vector<std::map<STRING,Ptr<MgDisposable> >*>* const), //the method on the [primaryDictionary] to read the actual MgCS item from
/*IN, optional*/ const std::vector<std::map<STRING,Ptr<MgDisposable> >*>* const secondaryDictionaryInfos, //infos that have been read from the dictionaries before; will be passed to [V::*GetMgItem]
@@ -275,28 +361,49 @@
throw new MgNullArgumentException(L"MentorDictionary.ReadAllDefinitionsCascaded", __LINE__, __WFILE__, NULL, L"", NULL);
//method pointer checks
- if (NULL == GetMgItem || NULL == CS_Trd)
+ if (NULL == GetMgItem || NULL == CS_TrdAll)
throw new MgNullArgumentException(L"MentorDictionary.ReadAllDefinitionsCascaded", __LINE__, __WFILE__, NULL, L"", NULL);
- auto_ptr<vector<U> > allDefs(MentorDictionary::ReadDictionaryEntries<U>(primaryDictionary, CS_Trd));
- if (NULL == allDefs.get()) //[ReadDictionaryEntries] will return NULL, if the dictionary entries couldn't be read
- throw new MgInvalidArgumentException(L"MgCoordinateSystemDictionary.ReadAllCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
+ U** pDefArray = NULL;
+ const int readStatus = CS_TrdAll(&pDefArray);
+ if (readStatus < 0)
+ {
+ _ASSERT(NULL == pDefArray);
+ throw new MgCoordinateSystemLoadFailedException(L"MgCoordinateSystemDictionary.ReadAllCoordinateSystems", __LINE__, __WFILE__, NULL, L"", NULL);
+ }
const bool doPostProcess = (NULL != PostProcess);
Ptr<MgDisposableCollection> filteredDefinitions = new MgDisposableCollection();
- //go through all defs as we've read them from CsMap, do some post processing and finally
- //retrieve the MgCs item we'll later return to the caller
- for(typename vector<U>::size_type i = 0; i < allDefs->size(); i++)
- {
- U csMapDef = allDefs->at(i); //don't work on the reference
- if (doPostProcess)
- CALL_MEMBER_FN(primaryDictionary, PostProcess)(&csMapDef);
+ MG_TRY()
- Ptr<T> mgItem = CALL_MEMBER_FN(primaryDictionary, GetMgItem)(&csMapDef, secondaryDictionaryInfos); //throws an exception, if the entry hasn't been found
- filteredDefinitions->Add(mgItem);
- }
+ //go through all defs as we've read them from CsMap, do some post processing and finally
+ //retrieve the MgCs item we'll later return to the caller
+ for(int i = 0; i < readStatus; ++i)
+ {
+ U* csMapDef = pDefArray[i];
+ if (doPostProcess)
+ CALL_MEMBER_FN(primaryDictionary, PostProcess)(csMapDef);
+ Ptr<T> mgItem = CALL_MEMBER_FN(primaryDictionary, GetMgItem)(csMapDef, secondaryDictionaryInfos); //throws an exception, if the entry hasn't been found
+ CS_free(csMapDef);
+ pDefArray[i] = NULL;
+
+ filteredDefinitions->Add(mgItem);
+ }
+
+ MG_CATCH(L"MentorDictionary.ReadAllDefinitions")
+
+ if (NULL != mgException) //the array's elements have been cleaned up otherwise already
+ {
+ for(int i = 0; i < readStatus; ++i)
+ CS_free(pDefArray[i]);
+ }
+
+ CS_free(pDefArray);
+
+ MG_THROW()
+
//we might get the same reference back - what isn't a problem as we're using the Ptr<> here
filteredDefinitions = MentorDictionary::FilterDefinitions<MgCoordinateSystem>(filteredDefinitions, filters);
return filteredDefinitions.Detach();
Modified: trunk/MgDev/Common/CoordinateSystem/MentorUtil.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/MentorUtil.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/MentorUtil.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -28,6 +28,7 @@
struct cs_Eldef_;
struct cs_Dtdef_;
struct cs_Csdef_;
+struct cs_Ctdef_;
struct cs_Datum_;
struct cs_Csprm_;
struct cs_Dtcprm_;
Modified: trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/SmartCriticalClass.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -21,7 +21,7 @@
class SmartCriticalClass
{
public:
- SmartCriticalClass(bool bEnter);
+ SmartCriticalClass(bool bEnter = true);
~SmartCriticalClass();
void Enter();
Modified: trunk/MgDev/Common/CoordinateSystem/namestruct.h
===================================================================
--- trunk/MgDev/Common/CoordinateSystem/namestruct.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/CoordinateSystem/namestruct.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -43,6 +43,7 @@
#pragma once
#include <list>
+#include <vector>
#include <map>
#include "cs_map.h" //for cs_KEYNM_DEF
@@ -111,21 +112,8 @@
typedef std::map<CSystemName, CSystemDescription> CSystemNameDescriptionMap;
typedef std::pair<CSystemName, CSystemDescription> CSystemNameDescriptionPair;
-//Max length of a category "name" (really, description).
-//The value chosen here is admittedly arbitrary. This is also
-//a new constraint, as ADE.PRO allowed arbitrarily long category
-//names. However I scanned the ADE.PRO which shipped with Map 3,
-//and the longest description therein was only 29 characters, so
-//this size should be more than ample.
-//
-//Note: Be careful about changing this number! It determines the
-//format of the category dictionary file, so changing this number
-//will render the public API unable to access any category dictionaries
-//which were created using a different number.
-const int knMaxCategoryNameLen = 128;
-
typedef TNameStruct CCategoryName;
typedef std::map<CCategoryName, long> CCategoryNameIndexMap;
-typedef std::list<CCategoryName> CCategoryNameList;
+typedef std::vector<CCategoryName> CCategoryNameList;
#endif //MG_NAMESTRUCT_H
Modified: trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h
===================================================================
--- trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Common/Geometry/CoordinateSystem/CoordinateSystemCatalog.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -48,6 +48,39 @@
virtual void SetDictionaryDir(CREFSTRING sDirPath)=0;
virtual STRING GetDictionaryDir()=0;
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns the default directory path where user defined coordinate system
+ /// definitions can be found or can be written into, respectively.
+ /// If set, this method returns the value of the MENTOR_USER_DICTIONARY_PATH
+ /// environment variable. Returns 'CSIDL_LOCAL_APPDATA\Autodesk\User Geospatial Coordinate Systems'
+ /// on Windows systems or an empty string on non-Windows systems, otherwise.
+ ///
+ /// \remarks
+ /// The directory returned by this function is not guaranteed to exist. If it does, however,
+ /// and is writable, too, the value returned by this function will be used to initialize this catalog of definitions
+ /// on the first initialization.
+ ///
+ virtual STRING GetDefaultUserDictionaryDir()=0;
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Sets the actual directory where user defined coordinate system
+ /// definitions can be found or can be written into. The directory set through this method must exist
+ /// and writeable. If set to an empty string, the catalog's 'user defined coordinate system' directory
+ /// will be unset and any updates will again happen only inside the directory
+ /// as returned by GetDictionaryDir().
+ ///
+ virtual void SetUserDictionaryDir(CREFSTRING sDirPath)=0;
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// \brief
+ /// Returns the current directory where user defined coordinate system
+ /// definitions is obtained from or is written into. Returns an empty string
+ /// if no such directory is currently configured for this catalog.
+ ///
+ virtual STRING GetUserDictionaryDir()=0;
+
virtual void SetProtectionMode(INT16 nMode)=0;
virtual INT16 GetProtectionMode()=0;
Modified: trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.cpp 2012-10-08 21:27:08 UTC (rev 7097)
@@ -100,6 +100,517 @@
///----------------------------------------------------------------------------
/// Test Case Description:
///
+/// The following test cases try reading all types of definitions from the current catalog
+///----------------------------------------------------------------------------
+
+//our helper method to read all definitions from all dictionaries
+#define CALL_MEMBER_FN(object,ptrToMember) ((object)->*(ptrToMember))
+template<
+ class MgCsType, class MgCsDictionaryType,
+ STRING (MgCsType::*GetCode)(),
+ MgCsDictionaryType* (MgCoordinateSystemCatalog::*MgGetDictionaryFunc)()>
+void TestReadAllDefinitions(wchar_t const* pzswDefType)
+{
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nReading all %W, ... "), pzswDefType));
+
+ MgCoordinateSystemFactory csFactory;
+ Ptr<MgCoordinateSystemCatalog> pMgCsCatalog = csFactory.GetCatalog();
+
+ Ptr<MgCsDictionaryType> pCsDictionary = CALL_MEMBER_FN(pMgCsCatalog, MgGetDictionaryFunc)();
+ Ptr<MgCoordinateSystemEnum> pCsEnum = pCsDictionary->GetEnum();
+ UINT32 size = pCsDictionary->GetSize();
+
+ CPPUNIT_ASSERT(size > 0); //by default, we're assuming to have 'something' in each dictionary
+
+ std::vector<STRING> allCodes;
+
+ bool firstFullSetDone = false;
+ Ptr<MgDisposableCollection> pNextCsDefinitions;
+ do
+ {
+ pNextCsDefinitions = pCsEnum->Next(size);
+ CPPUNIT_ASSERT(pNextCsDefinitions);
+
+ const INT32 defCount = pNextCsDefinitions->GetCount();
+ if (firstFullSetDone)
+ {
+ CPPUNIT_ASSERT(0 == defCount);
+ }
+ else
+ {
+ firstFullSetDone = true;
+ ACE_DEBUG((LM_INFO, ACE_TEXT("found %d definitions ...\n"), defCount));
+ }
+
+ for(INT32 i = 0; i < defCount; ++i)
+ {
+ Ptr<MgDisposable> pCsDisposable = pNextCsDefinitions->GetItem(i);
+
+ MgCsType* pDefinition = dynamic_cast<MgCsType*>(pCsDisposable.p);
+ CPPUNIT_ASSERT(pDefinition); //the collection must only contain objects of the required type
+
+ STRING code = CALL_MEMBER_FN(pDefinition, GetCode)();
+ CPPUNIT_ASSERT(!code.empty());
+ allCodes.push_back(code);
+ }
+
+ } while (pNextCsDefinitions->GetCount() > 0);
+
+ CPPUNIT_ASSERT(allCodes.size() == pCsDictionary->GetSize());
+
+ for(size_t i = 0; i < allCodes.size(); ++i)
+ {
+ STRING const& code = allCodes[i];
+ Ptr<MgDisposable> pDictionaryDef = pCsDictionary->Get(code);
+ MgCsType *pConcreteDef = dynamic_cast<MgCsType*>(pDictionaryDef.p);
+ CPPUNIT_ASSERT(pConcreteDef);
+
+ STRING codeFromDef = CALL_MEMBER_FN(pConcreteDef, GetCode)();
+ CPPUNIT_ASSERT(0 == _wcsicmp(codeFromDef.c_str(), code.c_str()));
+ }
+}
+
+/// (1) Read all Coordinate systems
+void TestCoordinateSystem::TestCase_ReadAllCoordinateSystems()
+{
+ TestReadAllDefinitions<MgCoordinateSystem, MgCoordinateSystemDictionary,
+ &MgCoordinateSystem::GetCsCode,
+ &MgCoordinateSystemCatalog::GetCoordinateSystemDictionary>(L"Coordinate Systems");
+}
+
+/// (2) Read all datums
+void TestCoordinateSystem::TestCase_ReadAllDatums()
+{
+ TestReadAllDefinitions<MgCoordinateSystemDatum, MgCoordinateSystemDatumDictionary,
+ &MgCoordinateSystemDatum::GetDtCode,
+ &MgCoordinateSystemCatalog::GetDatumDictionary>(L"Datums");
+}
+
+/// (3) Read all ellipsoids
+void TestCoordinateSystem::TestCase_ReadAllEllipsoids()
+{
+ TestReadAllDefinitions<MgCoordinateSystemEllipsoid, MgCoordinateSystemEllipsoidDictionary,
+ &MgCoordinateSystemEllipsoid::GetElCode,
+ &MgCoordinateSystemCatalog::GetEllipsoidDictionary>(L"Ellipsoids");
+}
+
+/// (4) Read all categories
+void TestCoordinateSystem::TestCase_ReadAllCategories()
+{
+ TestReadAllDefinitions<MgCoordinateSystemCategory, MgCoordinateSystemCategoryDictionary,
+ &MgCoordinateSystemCategory::GetName,
+ &MgCoordinateSystemCatalog::GetCategoryDictionary>(L"Categories");
+}
+
+/// (5) Read all geodetic transformations
+void TestCoordinateSystem::TestCase_ReadAllGeodeticTransformations()
+{
+ TestReadAllDefinitions<MgCoordinateSystemGeodeticTransformDef, MgCoordinateSystemGeodeticTransformDefDictionary,
+ &MgCoordinateSystemGeodeticTransformDef::GetTransformName,
+ &MgCoordinateSystemCatalog::GetGeodeticTransformDefDictionary>(L"Geodetic Transformations");
+}
+
+/// (6) Read all geodetic paths
+void TestCoordinateSystem::TestCase_ReadAllGeodeticPaths()
+{
+ TestReadAllDefinitions<MgCoordinateSystemGeodeticPath, MgCoordinateSystemGeodeticPathDictionary,
+ &MgCoordinateSystemGeodeticPath::GetPathName,
+ &MgCoordinateSystemCatalog::GetGeodeticPathDictionary>(L"Geodetic Paths");
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// The following test cases try updating all types of definitions in the current catalog
+///----------------------------------------------------------------------------
+///
+
+//our helper functions
+template<class MgCsType>
+void SetDefinitionUnprotected(MgCsType* pDefinition)
+{
+ pDefinition->SetProtectMode(false);
+}
+
+template<class MgCsType>
+MgCsType* CloneDefinition(MgCsType* pDefinition)
+{
+ return pDefinition->CreateClone();
+}
+
+template<
+ bool TAutoRemove,
+ bool TWithUserDefDir,
+ class MgCsType, class MgCsDictionaryType,
+ STRING (MgCsType::*GetCode)(),
+ void (MgCsType::*SetCode)(CREFSTRING),
+ MgCsDictionaryType* (MgCoordinateSystemCatalog::*MgGetDictionaryFunc)()>
+STRING TestUpdateDefinition(wchar_t const* pzswDefType,
+ void (*UnprotecDefFunc)(MgCsType*) = SetDefinitionUnprotected<MgCsType>,
+ MgCsType* (*CloneDefFunc)(MgCsType*) = NULL)
+{
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nUpdating a %W definition ... "), pzswDefType));
+
+ MgCoordinateSystemFactory csFactory;
+ Ptr<MgCoordinateSystemCatalog> pMgCsCatalog = csFactory.GetCatalog();
+
+ if (TWithUserDefDir)
+ {
+ TestCoordinateSystem::SetDefaultUserDictionaryDir();
+ }
+ else
+ {
+ if (!pMgCsCatalog->GetUserDictionaryDir().empty())
+ pMgCsCatalog->SetUserDictionaryDir(L"");
+ }
+
+ Ptr<MgCsDictionaryType> pCsDictionary = CALL_MEMBER_FN(pMgCsCatalog, MgGetDictionaryFunc)();
+ Ptr<MgCoordinateSystemEnum> pCsEnum = pCsDictionary->GetEnum();
+ UINT32 size = pCsDictionary->GetSize();
+
+ CPPUNIT_ASSERT(size > 0); //by default, we're assuming to have 'something' in each dictionary
+
+ Ptr<MgDisposableCollection> pNextCsDefinitions;
+ pNextCsDefinitions = pCsEnum->Next(1);
+
+ INT32 definitionCount = pNextCsDefinitions->GetCount();
+ CPPUNIT_ASSERT(1 == definitionCount);
+
+ Ptr<MgDisposable> pMgDefinition = pNextCsDefinitions->GetItem(0);
+ CPPUNIT_ASSERT(pMgDefinition);
+
+ MgCsType* pTypedDef = dynamic_cast<MgCsType*>(pMgDefinition.p);
+ CPPUNIT_ASSERT(NULL != pTypedDef);
+
+ STRING code = CALL_MEMBER_FN(pTypedDef, GetCode)();
+ CPPUNIT_ASSERT(!code.empty());
+
+ ACE_DEBUG((LM_INFO, ACE_TEXT("trying with %W ... "), code.c_str()));
+
+ //get us a definition we can modify
+ if (NULL != UnprotecDefFunc)
+ {
+ UnprotecDefFunc(pTypedDef);
+ }
+ else if (NULL != CloneDefFunc)
+ {
+ pMgDefinition = CloneDefFunc(pTypedDef);
+ pTypedDef = dynamic_cast<MgCsType*>(pMgDefinition.p);
+ CPPUNIT_ASSERT(NULL != pTypedDef);
+ }
+
+ STRING newCode = (code + L"_MOD");
+ CALL_MEMBER_FN(pTypedDef, SetCode)(newCode);
+
+ STRING csdFile = pCsDictionary->GetPath();
+ //backup the current CSD file and automatically restore it after we are done; or delete the newly created CSD file
+ //make sure, we keep the current file
+ TestCoordinateSystem::FileAutoBackup csdFileBackup(csdFile, L".UNIT_TEST_SAVE", true);
+
+ pCsDictionary->Add(pTypedDef);
+
+ Ptr<MgDisposable> pAddedDefinition = pCsDictionary->Get(newCode);
+ CPPUNIT_ASSERT(pAddedDefinition);
+
+ ACE_DEBUG((LM_INFO, ACE_TEXT("OK")));
+
+ CPPUNIT_ASSERT( pCsDictionary->Has(newCode) );
+
+ if (TAutoRemove)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT("... Remove it again... ")));
+ pCsDictionary->Remove(newCode);
+ CPPUNIT_ASSERT( !pCsDictionary->Has(newCode) );
+
+ ACE_DEBUG((LM_INFO, ACE_TEXT("OK")));
+ }
+
+ return newCode;
+}
+
+/// (1) Update a coordinate system
+void TestCoordinateSystem::TestCase_UpdateCoordinateSystems()
+{
+ TestUpdateDefinition<
+ true, /* compile as 'auto-remove function' */
+ false, /* compile as 'no-user-def-dir'*/
+ MgCoordinateSystem, MgCoordinateSystemDictionary,
+ &MgCoordinateSystem::GetCsCode,
+ &MgCoordinateSystem::SetCsCode,
+ &MgCoordinateSystemCatalog::GetCoordinateSystemDictionary>(L"Coordinate System");
+}
+
+/// (2) Update a datum
+void TestCoordinateSystem::TestCase_UpdateDatums()
+{
+ TestUpdateDefinition<
+ true, /* compile as 'auto-remove function' */
+ false, /* compile as 'no-user-def-dir'*/
+ MgCoordinateSystemDatum, MgCoordinateSystemDatumDictionary,
+ &MgCoordinateSystemDatum::GetDtCode,
+ &MgCoordinateSystemDatum::SetDtCode,
+ &MgCoordinateSystemCatalog::GetDatumDictionary>(L"Datum");
+}
+
+/// (3) Update an ellipsoid
+void TestCoordinateSystem::TestCase_UpdateEllipsoids()
+{
+ TestUpdateDefinition<
+ true, /* compile as 'auto-remove function' */
+ false, /* compile as 'no-user-def-dir'*/
+ MgCoordinateSystemEllipsoid, MgCoordinateSystemEllipsoidDictionary,
+ &MgCoordinateSystemEllipsoid::GetElCode,
+ &MgCoordinateSystemEllipsoid::SetElCode,
+ &MgCoordinateSystemCatalog::GetEllipsoidDictionary>(L"Ellipsoid");
+}
+
+/// (4) Update a category
+void TestCoordinateSystem::TestCase_UpdateCategories()
+{
+ TestUpdateDefinition<
+ true, /* compile as 'auto-remove function' */
+ false, /* compile as 'no-user-def-dir'*/
+ MgCoordinateSystemCategory, MgCoordinateSystemCategoryDictionary,
+ &MgCoordinateSystemCategory::GetName,
+ &MgCoordinateSystemCategory::SetName,
+ &MgCoordinateSystemCatalog::GetCategoryDictionary>(L"Category", NULL, NULL);
+}
+
+/// (5) Update a geodetic transformation
+void TestCoordinateSystem::TestCase_UpdateGeodeticTransformations()
+{
+ TestUpdateDefinition<
+ true, /* compile as 'auto-remove function' */
+ false, /* compile as 'no-user-def-dir'*/
+ MgCoordinateSystemGeodeticTransformDef, MgCoordinateSystemGeodeticTransformDefDictionary,
+ &MgCoordinateSystemGeodeticTransformDef::GetTransformName,
+ &MgCoordinateSystemGeodeticTransformDef::SetTransformName,
+ &MgCoordinateSystemCatalog::GetGeodeticTransformDefDictionary>(L"Geodetic Transformation", NULL, CloneDefinition);
+}
+
+/// (5) Update a geodetic path
+void TestCoordinateSystem::TestCase_UpdateGeodeticPaths()
+{
+ TestUpdateDefinition<
+ true, /* compile as 'auto-remove function' */
+ false, /* compile as 'no-user-def-dir'*/
+ MgCoordinateSystemGeodeticPath, MgCoordinateSystemGeodeticPathDictionary,
+ &MgCoordinateSystemGeodeticPath::GetPathName,
+ &MgCoordinateSystemGeodeticPath::SetPathName,
+ &MgCoordinateSystemCatalog::GetGeodeticPathDictionary>(L"Geodetic Path", NULL, CloneDefinition);
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// Tries setting a user dictionary path where to store CS user information into
+///----------------------------------------------------------------------------
+void TestCoordinateSystem::TestCase_InitializeValidUserDictionaryDir()
+{
+ MgCoordinateSystemFactory mgCsFactory;
+ Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+
+ STRING userDictionaryDir = pCsCatalog->GetDefaultUserDictionaryDir();
+ if (userDictionaryDir.empty())
+ return;
+
+ //create the directory to make sure, [SetUserDictionaryDir]
+ //can succeed
+ MgFileUtil::CreateDirectory(userDictionaryDir);
+
+ pCsCatalog->SetUserDictionaryDir(userDictionaryDir);
+ STRING setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+ CPPUNIT_ASSERT(setUserDictionaryDir == userDictionaryDir);
+
+ pCsCatalog->SetUserDictionaryDir(L"");
+ setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+ CPPUNIT_ASSERT(setUserDictionaryDir.empty());
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// Tries setting an invalid user dictionary path where to store CS user information into
+///----------------------------------------------------------------------------
+void TestCoordinateSystem::TestCase_InitializeInvalidUserDictionaryDir()
+{
+ MgCoordinateSystemFactory mgCsFactory;
+ Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+
+ STRING userDictionaryDir = pCsCatalog->GetDefaultUserDictionaryDir();
+ if (userDictionaryDir.empty())
+ return;
+
+ STRING setUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+ pCsCatalog->SetUserDictionaryDir(userDictionaryDir);
+
+ MG_TRY()
+
+#ifdef _WIN32
+ pCsCatalog->SetUserDictionaryDir(L"X:\\I am a hopefully not existing path - if I do, changeme");
+#else
+ pCsCatalog->SetUserDictionaryDir(L"/I a hopefully not existing path - if I do, changeme");
+#endif
+
+ MG_CATCH_AND_RELEASE()
+
+ CPPUNIT_ASSERT(NULL != mgException); //this *must* result in an exception
+
+ STRING currentUserDictionaryDir = pCsCatalog->GetUserDictionaryDir();
+ CPPUNIT_ASSERT(setUserDictionaryDir == currentUserDictionaryDir); //the current user dictionary path must not have changed
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
+/// The following test cases try updating all types of definitions in the current catalog
+/// with a user dictionary path being set
+///----------------------------------------------------------------------------
+///
+
+bool TestCoordinateSystem::SetDefaultUserDictionaryDir()
+{
+ MgCoordinateSystemFactory mgCsFactory;
+ Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+
+ STRING defUserDictionaryDir = pCsCatalog->GetDefaultUserDictionaryDir();
+ if (defUserDictionaryDir.empty())
+ {
+ defUserDictionaryDir = MgFileUtil::GetTempPath();
+ if (defUserDictionaryDir.empty())
+ return false;
+
+ defUserDictionaryDir += L"User Geospatial Coordinate Systems/";
+ }
+
+ //create the directory to make sure, [SetUserDictionaryDir]
+ //can succeed
+ MgFileUtil::CreateDirectory(defUserDictionaryDir);
+ pCsCatalog->SetUserDictionaryDir(defUserDictionaryDir);
+
+ return true;
+}
+
+template<
+ class MgCsType, class MgCsDictionaryType,
+ STRING (MgCsType::*GetCode)(),
+ void (MgCsType::*SetCode)(CREFSTRING),
+ MgCsDictionaryType* (MgCoordinateSystemCatalog::*MgGetDictionaryFunc)()>
+void TestUpdateUserDefinition(wchar_t const* pzswDefType,
+ void (*UnprotecDefFunc)(MgCsType*) = SetDefinitionUnprotected<MgCsType>,
+ MgCsType* (*CloneDefFunc)(MgCsType*) = NULL)
+{
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nTrying to set the default user dictionary path ...\n")));
+
+ bool userDirSet = TestCoordinateSystem::SetDefaultUserDictionaryDir();
+ if (!userDirSet)
+ {
+ ACE_DEBUG((LM_WARNING, ACE_TEXT("\nCould not set the default user dictionary path. Current test will be skipped\n")));
+ return;
+ }
+
+ MgCoordinateSystemFactory mgCsFactory;
+ Ptr<MgCoordinateSystemCatalog> pCsCatalog = mgCsFactory.GetCatalog();
+ Ptr<MgCsDictionaryType> pCsDictionary = CALL_MEMBER_FN(pCsCatalog, MgGetDictionaryFunc)();
+
+ const STRING& csCsdFilename = pCsDictionary->GetFileName();
+
+ STRING csCsdFile = pCsDictionary->GetPath();
+ CPPUNIT_ASSERT(!csCsdFile.empty());
+ CPPUNIT_ASSERT(MgFileUtil::IsFile(csCsdFile));
+
+ const INT64 csdFileSize = MgFileUtil::GetFileSize(csCsdFile);
+
+ STRING userDir = pCsCatalog->GetUserDictionaryDir();
+ STRING csCsdUserFile = userDir + csCsdFilename;
+
+ STRING addedCode;
+ {
+ //backup the current user CSD file and automatically restore it after we are done; or delete the newly created CSD file
+ TestCoordinateSystem::FileAutoBackup csdFileBackup(csCsdUserFile, L".UNIT_TEST_SAVE");
+
+ addedCode = TestUpdateDefinition<
+ false /* compile as 'no-auto-remove' */,
+ true /* compile as 'with-user-def-dir' */,
+ MgCsType, MgCsDictionaryType,
+ GetCode,
+ SetCode,
+ MgGetDictionaryFunc>(pzswDefType, UnprotecDefFunc, CloneDefFunc);
+
+ const INT64 updateCsdFileSize = MgFileUtil::GetFileSize(csCsdFile);
+ CPPUNIT_ASSERT(updateCsdFileSize == csdFileSize);
+
+ //the user CSD file now must exist
+ struct _stat fileStatus;
+ bool fileExists = MgFileUtil::GetFileStatus(csCsdUserFile, fileStatus);
+ CPPUNIT_ASSERT(fileExists && fileStatus.st_size);
+
+ CPPUNIT_ASSERT(!addedCode.empty());
+ CPPUNIT_ASSERT(pCsDictionary->Has(addedCode));
+ }
+
+ //now, that the user file had been deleted, our newly added definition must have been gone, too
+ pCsDictionary->SetFileName(pCsDictionary->GetFileName()); //force the Mg dictionary to update is cache
+ CPPUNIT_ASSERT(!pCsDictionary->Has(addedCode));
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserCoordinateSystems()
+{
+ TestUpdateUserDefinition<
+ MgCoordinateSystem, MgCoordinateSystemDictionary,
+ &MgCoordinateSystem::GetCsCode,
+ &MgCoordinateSystem::SetCsCode,
+ &MgCoordinateSystemCatalog::GetCoordinateSystemDictionary>(L"Coordinate System");
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserDatums()
+{
+ TestUpdateUserDefinition<
+ MgCoordinateSystemDatum, MgCoordinateSystemDatumDictionary,
+ &MgCoordinateSystemDatum::GetDtCode,
+ &MgCoordinateSystemDatum::SetDtCode,
+ &MgCoordinateSystemCatalog::GetDatumDictionary>(L"Datum");
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserEllipsoids()
+{
+ TestUpdateUserDefinition<
+ MgCoordinateSystemEllipsoid, MgCoordinateSystemEllipsoidDictionary,
+ &MgCoordinateSystemEllipsoid::GetElCode,
+ &MgCoordinateSystemEllipsoid::SetElCode,
+ &MgCoordinateSystemCatalog::GetEllipsoidDictionary>(L"Ellipsoid");
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserCategories()
+{
+ TestUpdateUserDefinition<
+ MgCoordinateSystemCategory, MgCoordinateSystemCategoryDictionary,
+ &MgCoordinateSystemCategory::GetName,
+ &MgCoordinateSystemCategory::SetName,
+ &MgCoordinateSystemCatalog::GetCategoryDictionary>(L"Category", NULL, NULL);
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserGeodeticTransformations()
+{
+ TestUpdateUserDefinition<
+ MgCoordinateSystemGeodeticTransformDef, MgCoordinateSystemGeodeticTransformDefDictionary,
+ &MgCoordinateSystemGeodeticTransformDef::GetTransformName,
+ &MgCoordinateSystemGeodeticTransformDef::SetTransformName,
+ &MgCoordinateSystemCatalog::GetGeodeticTransformDefDictionary>(L"Geodetic Transformation", NULL, CloneDefinition);
+}
+
+void TestCoordinateSystem::TestCase_UpdateUserGeodeticPaths()
+{
+ TestUpdateUserDefinition<
+ MgCoordinateSystemGeodeticPath, MgCoordinateSystemGeodeticPathDictionary,
+ &MgCoordinateSystemGeodeticPath::GetPathName,
+ &MgCoordinateSystemGeodeticPath::SetPathName,
+ &MgCoordinateSystemCatalog::GetGeodeticPathDictionary>(L"Geodetic Path", NULL, CloneDefinition);
+}
+
+///----------------------------------------------------------------------------
+/// Test Case Description:
+///
/// This test case loads OGC WKT coordinate systems from an external file and
/// tries to validate them.
///----------------------------------------------------------------------------
Modified: trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h
===================================================================
--- trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h 2012-10-08 13:55:53 UTC (rev 7096)
+++ trunk/MgDev/Server/src/UnitTesting/TestCoordinateSystem.h 2012-10-08 21:27:08 UTC (rev 7097)
@@ -25,6 +25,29 @@
CPPUNIT_TEST_SUITE(TestCoordinateSystem);
CPPUNIT_TEST(TestStart); // This must be the very first unit test
+ CPPUNIT_TEST(TestCase_ReadAllCoordinateSystems);
+ CPPUNIT_TEST(TestCase_ReadAllDatums);
+ CPPUNIT_TEST(TestCase_ReadAllEllipsoids);
+ CPPUNIT_TEST(TestCase_ReadAllCategories);
+ CPPUNIT_TEST(TestCase_ReadAllGeodeticTransformations);
+ CPPUNIT_TEST(TestCase_ReadAllGeodeticPaths);
+
+ CPPUNIT_TEST(TestCase_UpdateCoordinateSystems);
+ CPPUNIT_TEST(TestCase_UpdateDatums);
+ CPPUNIT_TEST(TestCase_UpdateEllipsoids);
+ CPPUNIT_TEST(TestCase_UpdateCategories);
+ CPPUNIT_TEST(TestCase_UpdateGeodeticTransformations);
+ CPPUNIT_TEST(TestCase_UpdateGeodeticPaths);
+
+ CPPUNIT_TEST(TestCase_InitializeValidUserDictionaryDir);
+
+ CPPUNIT_TEST(TestCase_UpdateUserCoordinateSystems);
+ CPPUNIT_TEST(TestCase_UpdateUserDatums);
+ CPPUNIT_TEST(TestCase_UpdateUserEllipsoids);
+ CPPUNIT_TEST(TestCase_UpdateUserCategories);
+ CPPUNIT_TEST(TestCase_UpdateUserGeodeticTransformations);
+ CPPUNIT_TEST(TestCase_UpdateUserGeodeticPaths);
+
CPPUNIT_TEST(TestCase_CheckCoordinateSystems);
CPPUNIT_TEST(TestCase_CreateValidCoordinateSystem);
CPPUNIT_TEST(TestCase_CreateInvalidCoordinateSystem);
@@ -235,6 +258,31 @@
void TestStart();
void TestEnd();
+ //check sanity of the dictionaries
+ void TestCase_ReadAllCoordinateSystems();
+ void TestCase_ReadAllDatums();
+ void TestCase_ReadAllEllipsoids();
+ void TestCase_ReadAllCategories();
+ void TestCase_ReadAllGeodeticTransformations();
+ void TestCase_ReadAllGeodeticPaths();
+
+ void TestCase_UpdateCoordinateSystems();
+ void TestCase_UpdateDatums();
+ void TestCase_UpdateEllipsoids();
+ void TestCase_UpdateCategories();
+ void TestCase_UpdateGeodeticTransformations();
+ void TestCase_UpdateGeodeticPaths();
+
+ void TestCase_InitializeInvalidUserDictionaryDir();
+ void TestCase_InitializeValidUserDictionaryDir();
+
+ void TestCase_UpdateUserCoordinateSystems();
+ void TestCase_UpdateUserDatums();
+ void TestCase_UpdateUserEllipsoids();
+ void TestCase_UpdateUserCategories();
+ void TestCase_UpdateUserGeodeticTransformations();
+ void TestCase_UpdateUserGeodeticPaths();
+
void TestCase_CheckCoordinateSystems();
void TestCase_CreateValidCoordinateSystem();
void TestCase_CreateInvalidCoordinateSystem();
@@ -438,6 +486,60 @@
// Performance
void TestCase_Benchmark_Transformation();
+ static bool SetDefaultUserDictionaryDir();
+
+ class FileAutoBackup
+ {
+ private:
+
+ STRING m_sFilename;
+ STRING m_sRotateSuffix;
+ STRING m_sBackupFilename;
+ bool m_bRotated;
+ bool m_bKeepFile;
+
+ public:
+ FileAutoBackup(const CREFSTRING filename, const CREFSTRING rotateSuffix, bool keepFile = false)
+ : m_sFilename(filename), m_sRotateSuffix(rotateSuffix), m_bRotated(false), m_bKeepFile(keepFile)
+ {
+ struct _stat fileStatus;
+ bool fileExists = MgFileUtil::GetFileStatus(filename, fileStatus);
+
+ this->m_sBackupFilename = (this->m_sFilename + this->m_sRotateSuffix);
+
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nBacking up file\n%W\n-->\n%W\n"), this->m_sFilename.c_str(), this->m_sBackupFilename.c_str()));
+
+ MgFileUtil::DeleteFile(this->m_sBackupFilename);
+ if (fileExists)
+ {
+ if (!this->m_bKeepFile)
+ {
+ MgFileUtil::RenameFile(this->m_sFilename, this->m_sBackupFilename);
+ }
+ else
+ {
+ MgFileUtil::CopyFile(this->m_sFilename, this->m_sBackupFilename);
+ }
+
+ this->m_bRotated = true;
+ }
+ }
+
+ ~FileAutoBackup()
+ {
+ MgFileUtil::DeleteFile(this->m_sFilename);
+ if (this->m_bRotated)
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nRestoring file\n%W\n-->\n%W\n"), this->m_sBackupFilename.c_str(), this->m_sFilename.c_str()));
+ MgFileUtil::RenameFile(this->m_sBackupFilename, this->m_sFilename, true);
+ }
+ else
+ {
+ ACE_DEBUG((LM_INFO, ACE_TEXT("\nDid not restore file\n%W\nas it did not exist before\n"), this->m_sFilename.c_str()));
+ }
+ }
+ };
+
private:
bool CompareCodes(STRING code1, STRING code2);
More information about the mapguide-commits
mailing list