Changes between Version 11 and Version 12 of MapGuideCodingStandards


Ignore:
Timestamp:
Jul 14, 2008, 11:41:42 AM (16 years ago)
Author:
jbirch
Comment:

checkpoint

Legend:

Unmodified
Added
Removed
Modified
  • MapGuideCodingStandards

    v11 v12  
    369369}}}
    370370
    371 === ForEach Statements ===
     371=== !ForEach Statements ===
    372372
    373373A foreach statement should have the following form:
     
    523523}}}
    524524
     525== Pointers ==
     526
     527=== Normal Pointers ===
     528
     529A pointer should always be checked before using. You should never assume that the pointer will be valid.
     530This is a good coding style and should be done.
     531{{{
     532#!cpp
     533if (pData != NULL)
     534{
     535        int nSize = pData->GetSize();
     536        ...
     537}
     538}}}
     539
     540This is a bad coding style and should not be done.
     541{{{
     542#!cpp
     543int nSize = pData->GetSize();
     544}}}
     545
     546When you are no longer using a pointer you should set it to NULL so that it is clear that it is no longer valid.
     547{{{
     548#!cpp
     549...
     550delete pData;
     551pData = NULL;
     552}}}
     553
     554=== Smart Pointers ===
     555
     556==== Our Code ====
     557
     558The !MapGuide Ptr template class acts as a smart pointer and should be used whenever possible.
     559Example:
     560{{{
     561#!cpp
     562MgRepository* MgServerResourceService::CreateRepository(CREFSTRING repositoryType, CREFSTRING repositoryName)
     563{
     564    Ptr<MgRepository> repository = 0;
     565
     566    MG_RESOURCE_SERVICE_TRY()
     567
     568    MgResourceServiceUtil::CheckArgument(!repositoryName.empty());
     569
     570    if (MgRepositoryType::Library == repositoryType)
     571    {
     572        repository = new MgLibraryRepository(repositoryName, this);
     573    }
     574    else if (MgRepositoryType::Session == repositoryType)
     575    {
     576        repository = new MgSessionRepository(repositoryName, this);
     577    }
     578    else
     579    {
     580        throw new MgInvalidRepositoryTypeException(__FILE__, __LINE__);
     581    }
     582
     583    MgResourceServiceUtil::CheckMemory(repository);
     584
     585    MG_RESOURCE_SERVICE_CATCH_AND_THROW()
     586
     587    assert(0 == mgException);
     588
     589    (*repository).AddRef();     // Ownership is transferred to the caller
     590
     591    return repository;
     592}
     593}}}
     594
     595==== 3rd Party Library ====
     596
     597Wherever possible the standard C++ smart pointer should be used when dealing with 3rd party libraries.
     598
     599The following is some sample code that uses the standard C++ smart pointer along with a typical !MapGuide Exception handling mechanism:
     600
     601{{{
     602#!cpp
     603Bar* Foo::CreateBar()
     604{
     605    auto_ptr<Bar> bar;
     606
     607    MG_TRY()
     608
     609    bar = auto_ptr<Bar>(new Bar);
     610    assert(0 != bar.get());
     611    bar.DoSomething(); // might throw an exception
     612
     613    MG_CATCH_AND_THROW()
     614
     615    return bar.release(); // release ownership of the smart pointer
     616}
     617}}}
     618 
     619Standard C++ smart pointer notes:
     620 1. Never use auto_ptr objects as elements of STL containers because auto_ptr does not quite meet the requirements of a type you can put into containers (i.e. copies of auto_ptrs are not equivalent).
     621 1. Never use an array as an auto_ptr argument because auto_ptr's destructor invokes only non-array delete.
     622
     623The following code is a cleaned up version of the above sample code using some helper macros.
     624{{{
     625#!cpp
     626Bar* Foo::CreateBar()
     627{
     628    char* bar = 0;
     629
     630    MG_TRY()
     631
     632    bar = new char[256];
     633    assert(0 != bar);
     634    DoSomething(bar);
     635
     636    MG_CATCH()
     637
     638    if (0 != mgException)
     639    {
     640        delete[] bar;
     641        throw mgException;
     642    }
     643
     644    return bar;
     645}
     646}}}
     647
     648Note that MG_TRY(), MG_CATCH(), MG_THROW, MG_CATCH_AND_THROW and MG_CATCH_AND_RELEASE() macros can be anything specific to a !MapGuide component.
     649 
     650Example macro definitions for the resource service:
     651{{{
     652#!cpp
     653#define MG_RESOURCE_SERVICE_TRY()                                             \
     654    MG_TRY()                                                                  \
     655
     656#define MG_RESOURCE_SERVICE_CATCH(methodName)                                 \
     657    }                                                                         \
     658    catch (XmlException& e)                                                   \
     659    {                                                                         \
     660        MgStringCollection arguments;                                         \
     661        STRING message;                                                       \
     662                                                                              \
     663        if (DB_LOCK_DEADLOCK == e.getDbErrno())                               \
     664        {                                                                     \
     665            message = MgUtil::GetResourceMessage(                             \
     666                MgResources::ResourceService, L"MgRepositoryBusy");           \
     667        }                                                                     \
     668        else                                                                  \
     669        {                                                                     \
     670            MgUtil::MultiByteToWideChar(string(e.what()), message);           \
     671        }                                                                     \
     672                                                                              \
     673        arguments.Add(message);                                               \
     674        mgException = new MgDbXmlException(methodName, __LINE__, __WFILE__, NULL, L"MgFormatInnerExceptionMessage", &arguments); \
     675        (static_cast<MgThirdPartyException*>(mgException.p))->SetErrorCode(e.getDbErrno()); \
     676    }                                                                         \
     677    catch (DbException& e)                                                    \
     678    {                                                                         \
     679        MgStringCollection arguments;                                         \
     680        STRING message;                                                       \
     681                                                                              \
     682        if (DB_LOCK_DEADLOCK == e.get_errno())                                \
     683        {                                                                     \
     684            message = MgUtil::GetResourceMessage(                             \
     685                MgResources::ResourceService, L"MgRepositoryBusy");           \
     686        }                                                                     \
     687        else                                                                  \
     688        {                                                                     \
     689            MgUtil::MultiByteToWideChar(string(e.what()), message);           \
     690        }                                                                     \
     691                                                                              \
     692        arguments.Add(message);                                               \
     693        mgException = new MgDbException(methodName, __LINE__, __WFILE__, NULL, L"MgFormatInnerExceptionMessage", &arguments); \
     694        (static_cast<MgThirdPartyException*>(mgException.p))->SetErrorCode(e.get_errno()); \
     695    }                                                                         \
     696    catch (DWFException& e)                                                   \
     697    {                                                                         \
     698        MgStringCollection arguments;                                         \
     699        arguments.Add(STRING(e.message()));                                   \
     700        mgException = new MgDwfException(methodName, __LINE__, __WFILE__, NULL, L"MgFormatInnerExceptionMessage", &arguments); \
     701    }                                                                         \
     702    catch (const XMLException& e)                                             \
     703    {                                                                         \
     704        MgStringCollection arguments;                                         \
     705        arguments.Add(X2W(e.getMessage()));                                   \
     706        mgException = new MgXmlParserException(methodName, __LINE__, __WFILE__, NULL, L"MgFormatInnerExceptionMessage", &arguments); \
     707    }                                                                         \
     708    catch (const DOMException& e)                                             \
     709    {                                                                         \
     710        MgStringCollection arguments;                                         \
     711        arguments.Add(X2W(e.msg));                                            \
     712        mgException = new MgXmlParserException(methodName, __LINE__, __WFILE__, NULL, L"MgFormatInnerExceptionMessage", &arguments); \
     713                                                                              \
     714    MG_CATCH(methodName)                                                      \
     715
     716#define MG_RESOURCE_SERVICE_THROW()                                           \
     717    MG_THROW()                                                                \
     718
     719#define MG_RESOURCE_SERVICE_CATCH_AND_THROW(methodName)                       \
     720    MG_RESOURCE_SERVICE_CATCH(methodName)                                     \
     721                                                                              \
     722    MG_RESOURCE_SERVICE_THROW()                                               \
     723}}}
     724
     725== Enumerations ==
     726
     727Please use the following format when declaring enumerations.
     728
     729Example 1:
     730{{{
     731#!cpp
     732enum MgDimensionality
     733{
     734    mdXY = 0,   /// XY
     735    mdXYM,              /// XY + Measure
     736    mdXYZ,              /// XYZ
     737    mdXYZM,             /// XYZ + Measure
     738};
     739}}}
     740
     741Example 2:
     742{{{
     743#!cpp
     744enum MgConnectionState
     745{
     746    mcsOpen = 0,   /// Connection is still open
     747    mcsClose,      /// Connection has been closed
     748    mcsBusy        /// Connection is busy processing other request
     749};
     750}}}
     751
     752You will notice that the 1st letter of each word is part of the enumeration value.
     753Also, when using enumerations in your code ALWAYS do the following:
     754{{{
     755#!cpp
     756ConnectionState::mcsOpen
     757}}}
     758Do NOT do the following:
     759{{{
     760#!cpp
     761mcsOpen
     762}}}
     763
     764== Parentheses ==
     765
     766Even if the operator precedence seems clear to you, it is best to use parentheses to avoid any confusion by others.
     767{{{
     768#!cpp
     769if (a == b && c == d)     // Bad
     770if ((a == b) && (c == d)) // Good
     771}}}
     772
     773== Assert ==
     774
     775=== .NET ===
     776
     777Use Debug.Assert ( condition ) to do assertions. Do not use Trace.Assert as that will not be removed for release build.
     778
     779For C++ .NET projects you must do the following or else the Debug calls will still be called in release builds.
     780{{{
     781#!cpp
     782#ifdef _DEBUG
     783Debug::WriteLine(SrsErrorMessage(status));
     784#endif   
     785}}}
     786
     787
     788
     789