<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    "../../Characters/String.h"
#include    "../../Characters/String_Constant.h"
#include    "../../Memory/SmallStackBuffer.h"

#include    "PathName.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::FileSystem;

#if     qCompilerAndStdLib_constexpr_Buggy
#if     qPlatform_Windows
const   wchar_t   FileSystem::kPathComponentSeperator =   '\\';
#elif   qPlatform_POSIX
const   wchar_t   FileSystem::kPathComponentSeperator =   '/';
#endif
#endif

/*
 ********************************************************************************
 ************** FileSystem::AssureDirectoryPathSlashTerminated ******************
 ********************************************************************************
 */
String FileSystem::AssureDirectoryPathSlashTerminated (const String& dirPath)
{
    if (dirPath.empty ()) {
        AssertNotReached ();    // not sure if this is an error or not. Not sure how code used.
        // put assert in there to find out... Probably should THROW!
        //      -- LGP 2009-05-12
        return String (&kPathComponentSeperator, &kPathComponentSeperator + 1);
    }
    else {
        Character   lastChar = dirPath[dirPath.size () - 1];
        if (lastChar == kPathComponentSeperator) {
            return dirPath;
        }
        String result  =   dirPath;
        result += kPathComponentSeperator;
        return result;
    }
}

/*
 ********************************************************************************
 *********************** FileSystem::SafeFilenameChars **************************
 ********************************************************************************
 */
String FileSystem::SafeFilenameChars (const String& s)
{
    wstring tmp =   s.As<wstring> ();   // analyze as wide-char string so we don't mis-identify
    // characters (by looking at lead bytes etc)
Again:
    for (auto i = tmp.begin (); i != tmp.end (); ++i) {
        switch (*i) {
            case    '\\':
                *i = '_';
                break;
            case    '/':
                *i = '_';
                break;
            case    ':':
                *i = ' ';
                break;
            case    '.':
                tmp.erase (i);
                goto Again;
        }
    }
    return tmp;
}

/*
 ********************************************************************************
 ********************* FileSystem::AssureLongFileName ***************************
 ********************************************************************************
 */
String FileSystem::AssureLongFileName (const String& fileName)
{
#if     qPlatform_Windows
    DWORD   r   =   ::GetLongPathNameW (fileName.c_str (), nullptr, 0);
    if (r != 0) {
        Memory::SmallStackBuffer<wchar_t> buf (r);
        r = ::GetLongPathNameW (fileName.c_str (), buf, r);
        if (r != 0) {
            return static_cast<const wchar_t*> (buf);
        }
    }
#endif
    return fileName;
}

/*
 ********************************************************************************
 ************************** FileSystem::GetFileSuffix ***************************
 ********************************************************************************
 */
String FileSystem::GetFileSuffix (const String& fileName)
{
#if     qPlatform_Windows
    String useFName    =   fileName;
    {
        SDKChar   fNameBuf[4 * MAX_PATH];
        fNameBuf[0] = '\0';
        DISABLE_COMPILER_MSC_WARNING_START (4267)
        DWORD   r   =   ::GetLongPathName (fileName.AsSDKString ().c_str (), fNameBuf, NEltsOf (fNameBuf) - 1);
        DISABLE_COMPILER_MSC_WARNING_END (4267)
        if (r != 0) {
            useFName = String::FromSDKString (fNameBuf);
        }
    }
    SDKChar   fname[_MAX_FNAME] {};
    SDKChar   drive[_MAX_DRIVE] {};
    SDKChar   dir[_MAX_DIR] {};
    SDKChar   ext[_MAX_EXT] {};
    // @todo - probably should check result (errno_t) and throw?
    ::_tsplitpath_s (useFName.AsSDKString ().c_str (), drive, dir, fname, ext);
    // returns leading '.' in name...
    return String::FromSDKString (ext);
#else
    AssertNotImplemented ();
    return String ();
#endif
}

/*
 ********************************************************************************
 ************************ FileSystem::GetFileBaseName ***************************
 ********************************************************************************
 */
namespace {
    String  OLD_GetFileBaseName_ (const String& pathName)
    {
#if     qPlatform_POSIX
        String tmp =   pathName;
        // Examples to consider:
        //      /tmp/foo.txt ==> foo
        //      /tmp/foo/ ==> foo
        {
            size_t i = tmp.rfind ('/');
            if (i != String::kBadIndex) {
                tmp =  tmp.substr (i + 1);
            }
        }
        {
            size_t i = tmp.find ('.');
            // if the string
            if (i != String::kBadIndex and i != tmp.length ()) {
                tmp =  tmp.substr (0, i);
            }
        }
        return tmp;
#elif   qPlatform_Windows
        String useFName    =   pathName;
        {
            SDKChar   fNameBuf[4 * MAX_PATH ];
            DWORD   r   =   ::GetLongPathName (pathName.AsSDKString ().c_str (), fNameBuf, static_cast<DWORD> (NEltsOf (fNameBuf) - 1));
            if (r != 0) {
                useFName = String::FromSDKString (fNameBuf);
            }
        }
        SDKChar   fname[_MAX_FNAME] {};
        SDKChar   drive[_MAX_DRIVE] {};
        SDKChar   dir[_MAX_DIR] {};
        SDKChar   ext[_MAX_EXT] {};
        ::_tsplitpath_s (useFName.AsSDKString ().c_str (), drive, dir, fname, ext);
        return String::FromSDKString (fname);
#else
        AssertNotImplemented ();
#endif
    }
}
String FileSystem::GetFileBaseName (const String& pathName)
{
    String  baseName = ExtractDirAndBaseName (pathName).second;
    if (not baseName.empty () and baseName.GetCharAt (baseName.size () - 1) == kPathComponentSeperator) {
        baseName = baseName.RemoveAt (baseName.size () - 1);
    }
    {
        size_t i = baseName.find ('.');
        // Strip the trailing .XXX if that isn't the entire string
        if (i != String::kBadIndex and i != 0) {
            baseName =  baseName.SubString (0, i);
        }
    }
#if     qPlatform_Windows
    //tmphack to test - not REALLY a bug - if diff was cuz of GetLongPath
    Assert (baseName == OLD_GetFileBaseName_ (pathName) or (baseName.StartsWith (L".") and OLD_GetFileBaseName_ (pathName).empty ()));
#endif
    return baseName;
}

/*
 ********************************************************************************
 ******************** FileSystem::ExtractDirAndBaseName *************************
 ********************************************************************************
 */
pair<String, String> FileSystem::ExtractDirAndBaseName (const String& pathName)
{
    bool    endedWithSlash = false;
    String  dirname;
    String  basename;
    {
        String tmp =   pathName;
        while (not tmp.empty () and tmp.GetCharAt (tmp.size () - 1) == kPathComponentSeperator) {
            tmp = tmp.RemoveAt (tmp.size () - 1);
            endedWithSlash = true;
        }
        size_t i = tmp.rfind (kPathComponentSeperator);
        if (i == String::kBadIndex) {
            basename = tmp;
        }
        else {
            dirname = tmp.SubString (0, i + 1);
            basename =  tmp.SubString (i + 1);
        }
    }
    if (dirname.empty ()) {
        if (basename.empty ()) {
            dirname =  AssureDirectoryPathSlashTerminated (pathName);   // e.g. pathName = "/" and so we stripped trailing slashes down to nothing!
        }
        else {
            dirname =  AssureDirectoryPathSlashTerminated (L".");
        }
    }
    Assert (dirname == AssureDirectoryPathSlashTerminated (dirname));
    if (endedWithSlash and not basename.empty ()) {
        basename += kPathComponentSeperator;
    }
    return pair<String, String> { dirname, basename };
}

/*
 ********************************************************************************
 ************************ FileSystem::StripFileSuffix ***************************
 ********************************************************************************
 */
String FileSystem::StripFileSuffix (const String& pathName)
{
    String useFName    =   pathName;
    String fileSuffix  =   GetFileSuffix (pathName);
    if (useFName.length () > fileSuffix.length ()) {
        return useFName.substr (0, useFName.length () - fileSuffix.length ());
    }
    else {
        return useFName;
    }
}

/*
 ********************************************************************************
 ************************ FileSystem::GetFileDirectory **************************
 ********************************************************************************
 */
String FileSystem::GetFileDirectory (const String& pathName)
{
    // could use splitpath, but this maybe better, since works with \\UNCNAMES
    String  tmp     =   pathName;
    size_t  idx     =   tmp.rfind (kPathComponentSeperator);
    if (idx != String::kBadIndex) {
        tmp.erase (idx + 1);
    }
    return tmp;
}

<commit_msg>fixed FileSystem::GetFileBaseName () to use rfind (.)<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2016.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    "../../Characters/String.h"
#include    "../../Characters/String_Constant.h"
#include    "../../Memory/SmallStackBuffer.h"

#include    "PathName.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Characters;
using   namespace   Stroika::Foundation::IO;
using   namespace   Stroika::Foundation::IO::FileSystem;

#if     qCompilerAndStdLib_constexpr_Buggy
#if     qPlatform_Windows
const   wchar_t   FileSystem::kPathComponentSeperator =   '\\';
#elif   qPlatform_POSIX
const   wchar_t   FileSystem::kPathComponentSeperator =   '/';
#endif
#endif

/*
 ********************************************************************************
 ************** FileSystem::AssureDirectoryPathSlashTerminated ******************
 ********************************************************************************
 */
String FileSystem::AssureDirectoryPathSlashTerminated (const String& dirPath)
{
    if (dirPath.empty ()) {
        AssertNotReached ();    // not sure if this is an error or not. Not sure how code used.
        // put assert in there to find out... Probably should THROW!
        //      -- LGP 2009-05-12
        return String (&kPathComponentSeperator, &kPathComponentSeperator + 1);
    }
    else {
        Character   lastChar = dirPath[dirPath.size () - 1];
        if (lastChar == kPathComponentSeperator) {
            return dirPath;
        }
        String result  =   dirPath;
        result += kPathComponentSeperator;
        return result;
    }
}

/*
 ********************************************************************************
 *********************** FileSystem::SafeFilenameChars **************************
 ********************************************************************************
 */
String FileSystem::SafeFilenameChars (const String& s)
{
    wstring tmp =   s.As<wstring> ();   // analyze as wide-char string so we don't mis-identify
    // characters (by looking at lead bytes etc)
Again:
    for (auto i = tmp.begin (); i != tmp.end (); ++i) {
        switch (*i) {
            case    '\\':
                *i = '_';
                break;
            case    '/':
                *i = '_';
                break;
            case    ':':
                *i = ' ';
                break;
            case    '.':
                tmp.erase (i);
                goto Again;
        }
    }
    return tmp;
}

/*
 ********************************************************************************
 ********************* FileSystem::AssureLongFileName ***************************
 ********************************************************************************
 */
String FileSystem::AssureLongFileName (const String& fileName)
{
#if     qPlatform_Windows
    DWORD   r   =   ::GetLongPathNameW (fileName.c_str (), nullptr, 0);
    if (r != 0) {
        Memory::SmallStackBuffer<wchar_t> buf (r);
        r = ::GetLongPathNameW (fileName.c_str (), buf, r);
        if (r != 0) {
            return static_cast<const wchar_t*> (buf);
        }
    }
#endif
    return fileName;
}

/*
 ********************************************************************************
 ************************** FileSystem::GetFileSuffix ***************************
 ********************************************************************************
 */
String FileSystem::GetFileSuffix (const String& fileName)
{
#if     qPlatform_Windows
    String useFName    =   fileName;
    {
        SDKChar   fNameBuf[4 * MAX_PATH];
        fNameBuf[0] = '\0';
        DISABLE_COMPILER_MSC_WARNING_START (4267)
        DWORD   r   =   ::GetLongPathName (fileName.AsSDKString ().c_str (), fNameBuf, NEltsOf (fNameBuf) - 1);
        DISABLE_COMPILER_MSC_WARNING_END (4267)
        if (r != 0) {
            useFName = String::FromSDKString (fNameBuf);
        }
    }
    SDKChar   fname[_MAX_FNAME] {};
    SDKChar   drive[_MAX_DRIVE] {};
    SDKChar   dir[_MAX_DIR] {};
    SDKChar   ext[_MAX_EXT] {};
    // @todo - probably should check result (errno_t) and throw?
    ::_tsplitpath_s (useFName.AsSDKString ().c_str (), drive, dir, fname, ext);
    // returns leading '.' in name...
    return String::FromSDKString (ext);
#else
    AssertNotImplemented ();
    return String ();
#endif
}

/*
 ********************************************************************************
 ************************ FileSystem::GetFileBaseName ***************************
 ********************************************************************************
 */
namespace {
    String  OLD_GetFileBaseName_ (const String& pathName)
    {
#if     qPlatform_POSIX
        String tmp =   pathName;
        // Examples to consider:
        //      /tmp/foo.txt ==> foo
        //      /tmp/foo/ ==> foo
        {
            size_t i = tmp.rfind ('/');
            if (i != String::kBadIndex) {
                tmp =  tmp.substr (i + 1);
            }
        }
        {
            size_t i = tmp.find ('.');
            // if the string
            if (i != String::kBadIndex and i != tmp.length ()) {
                tmp =  tmp.substr (0, i);
            }
        }
        return tmp;
#elif   qPlatform_Windows
        String useFName    =   pathName;
        {
            SDKChar   fNameBuf[4 * MAX_PATH ];
            DWORD   r   =   ::GetLongPathName (pathName.AsSDKString ().c_str (), fNameBuf, static_cast<DWORD> (NEltsOf (fNameBuf) - 1));
            if (r != 0) {
                useFName = String::FromSDKString (fNameBuf);
            }
        }
        SDKChar   fname[_MAX_FNAME] {};
        SDKChar   drive[_MAX_DRIVE] {};
        SDKChar   dir[_MAX_DIR] {};
        SDKChar   ext[_MAX_EXT] {};
        ::_tsplitpath_s (useFName.AsSDKString ().c_str (), drive, dir, fname, ext);
        return String::FromSDKString (fname);
#else
        AssertNotImplemented ();
#endif
    }
}
String FileSystem::GetFileBaseName (const String& pathName)
{
    String  baseName = ExtractDirAndBaseName (pathName).second;
    if (not baseName.empty () and baseName.GetCharAt (baseName.size () - 1) == kPathComponentSeperator) {
        baseName = baseName.RemoveAt (baseName.size () - 1);
    }
    {
        size_t i = baseName.rfind ('.');
        // Strip the trailing .XXX if that isn't the entire string
        if (i != String::kBadIndex and i != 0) {
            baseName =  baseName.SubString (0, i);
        }
    }
#if     qPlatform_Windows
    //tmphack to test - not REALLY a bug - if diff was cuz of GetLongPath
    Assert (baseName == OLD_GetFileBaseName_ (pathName) or (baseName.StartsWith (L".") and OLD_GetFileBaseName_ (pathName).empty ()));
#endif
    return baseName;
}

/*
 ********************************************************************************
 ******************** FileSystem::ExtractDirAndBaseName *************************
 ********************************************************************************
 */
pair<String, String> FileSystem::ExtractDirAndBaseName (const String& pathName)
{
    bool    endedWithSlash = false;
    String  dirname;
    String  basename;
    {
        String tmp =   pathName;
        while (not tmp.empty () and tmp.GetCharAt (tmp.size () - 1) == kPathComponentSeperator) {
            tmp = tmp.RemoveAt (tmp.size () - 1);
            endedWithSlash = true;
        }
        size_t i = tmp.rfind (kPathComponentSeperator);
        if (i == String::kBadIndex) {
            basename = tmp;
        }
        else {
            dirname = tmp.SubString (0, i + 1);
            basename =  tmp.SubString (i + 1);
        }
    }
    if (dirname.empty ()) {
        if (basename.empty ()) {
            dirname =  AssureDirectoryPathSlashTerminated (pathName);   // e.g. pathName = "/" and so we stripped trailing slashes down to nothing!
        }
        else {
            dirname =  AssureDirectoryPathSlashTerminated (L".");
        }
    }
    Assert (dirname == AssureDirectoryPathSlashTerminated (dirname));
    if (endedWithSlash and not basename.empty ()) {
        basename += kPathComponentSeperator;
    }
    return pair<String, String> { dirname, basename };
}

/*
 ********************************************************************************
 ************************ FileSystem::StripFileSuffix ***************************
 ********************************************************************************
 */
String FileSystem::StripFileSuffix (const String& pathName)
{
    String useFName    =   pathName;
    String fileSuffix  =   GetFileSuffix (pathName);
    if (useFName.length () > fileSuffix.length ()) {
        return useFName.substr (0, useFName.length () - fileSuffix.length ());
    }
    else {
        return useFName;
    }
}

/*
 ********************************************************************************
 ************************ FileSystem::GetFileDirectory **************************
 ********************************************************************************
 */
String FileSystem::GetFileDirectory (const String& pathName)
{
    // could use splitpath, but this maybe better, since works with \\UNCNAMES
    String  tmp     =   pathName;
    size_t  idx     =   tmp.rfind (kPathComponentSeperator);
    if (idx != String::kBadIndex) {
        tmp.erase (idx + 1);
    }
    return tmp;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperNumericalParameter.h"

#include "otbVegetationIndicesFunctor.h"
#include "otbWaterIndicesFunctor.h"
#include "otbBuiltUpIndicesFunctor.h"
#include "otbSoilIndicesFunctor.h"
#include "otbIndicesStackFunctor.h"
#include "otbFunctorImageFilter.h"

namespace otb
{
namespace Wrapper
{

class RadiometricIndices: public Application
{
public:
  /** Standard class typedefs. */
  typedef RadiometricIndices       Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(RadiometricIndices, otb::Wrapper::Application);

  using InputType = FloatVectorImageType::InternalPixelType;
  using OutputType = FloatImageType::PixelType;

  using RadiometricIndiceType = otb::Functor::RadiometricIndice<InputType, OutputType>;
  using IndicesStackFunctorType = otb::Functor::IndicesStackFunctor<RadiometricIndiceType>;

  class indiceSpec
  {
  public:
    indiceSpec(std::string k, std::string i, RadiometricIndiceType * ind)
      : key(k), item(i), indice(ind)
    {}
    std::string key;
    std::string item;
    std::unique_ptr<RadiometricIndiceType> indice;
  };

private:
  void DoInit() override
  {
    SetName("RadiometricIndices");
    SetDescription("Compute radiometric indices.");

    // Documentation
    SetDocName("Radiometric Indices");
    SetDocLongDescription("This application computes radiometric indices using the relevant channels of the input image. The output is a multi band image into which each channel is one of the selected indices.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("otbVegetationIndicesFunctor, otbWaterIndicesFunctor and otbSoilIndicesFunctor classes");

    AddDocTag(Tags::FeatureExtraction);
	AddDocTag("Radiometric Indices");

    AddParameter(ParameterType_InputImage, "in", "Input Image");
    SetParameterDescription("in", "Input image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out", "Radiometric indices output image");

    AddParameter(ParameterType_Group, "channels", "Channels selection");
    SetParameterDescription("channels", "Channels selection");

    AddParameter(ParameterType_Int,  "channels.blue",  "Blue Channel");
    SetParameterDescription("channels.blue", "Blue channel index");
    SetDefaultParameterInt("channels.blue", 1);
    AddParameter(ParameterType_Int,  "channels.green",  "Green Channel");
    SetParameterDescription("channels.green", "Green channel index");
    SetDefaultParameterInt("channels.green", 1);
    AddParameter(ParameterType_Int,  "channels.red",  "Red Channel");
    SetParameterDescription("channels.red", "Red channel index");
    SetDefaultParameterInt("channels.red", 1);
    AddParameter(ParameterType_Int,  "channels.nir",  "NIR Channel");
    SetParameterDescription("channels.nir", "NIR channel index");
    SetDefaultParameterInt("channels.nir", 1);
    AddParameter(ParameterType_Int,  "channels.mir",  "Mir Channel");
    SetParameterDescription("channels.mir", "Mir channel index");
    SetDefaultParameterInt("channels.mir", 1);

    AddParameter(ParameterType_ListView,  "list", "Available Radiometric Indices");
    SetParameterDescription("list",
        "List of available radiometric indices with their relevant channels in brackets:\n\n"
        "* Vegetation:NDVI - Normalized difference vegetation index (Red, NIR)\n"
        "* Vegetation:TNDVI - Transformed normalized difference vegetation index (Red, NIR)\n"
        "* Vegetation:RVI - Ratio vegetation index (Red, NIR)\n"
        "* Vegetation:SAVI - Soil adjusted vegetation index (Red, NIR)\n"
        "* Vegetation:TSAVI - Transformed soil adjusted vegetation index (Red, NIR)\n"
        "* Vegetation:MSAVI - Modified soil adjusted vegetation index (Red, NIR)\n"
        "* Vegetation:MSAVI2 - Modified soil adjusted vegetation index 2 (Red, NIR)\n"
        "* Vegetation:GEMI - Global environment monitoring index (Red, NIR)\n"
        "* Vegetation:IPVI - Infrared percentage vegetation index (Red, NIR)\n"
        "* Water:NDWI - Normalized difference water index (Gao 1996) (NIR, MIR)\n"
        "* Water:NDWI2 - Normalized difference water index (Mc Feeters 1996) (Green, NIR)\n"
        "* Water:MNDWI - Modified normalized difference water index (Xu 2006) (Green, MIR)\n"
        "* Water:NDTI - Normalized difference turbidity index (Lacaux et al.) (Red, Green)\n"
        "* Soil:RI - Redness index (Red, Green)\n"
        "* Soil:CI - Color index (Red, Green)\n"
        "* Soil:BI - Brightness index (Red, Green)\n"
        "* Soil:BI2 - Brightness index 2 (NIR, Red, Green)");

    AddRAMParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
    SetDocExampleParameterValue("list", "Vegetation:NDVI Vegetation:RVI Vegetation:IPVI");
    SetDocExampleParameterValue("out", "RadiometricIndicesImage.tif");

    SetOfficialDocLink();

    m_Map.clear();

    m_Map.push_back({"list.ndvi","Vegetation:NDVI",new otb::Functor::NDVI<InputType,OutputType>()});
    m_Map.push_back({"list.tndvi","Vegetation:TNDVI",new otb::Functor::TNDVI<InputType,OutputType>()});
    m_Map.push_back({"list.rdvi","Vegetation:RVI",new otb::Functor::RVI<InputType,OutputType>()});
    m_Map.push_back({"list.savi","Vegetation:SAVI",new otb::Functor::SAVI<InputType,OutputType>()});
    m_Map.push_back({"list.tsavi","Vegetation:TSAVI",new otb::Functor::TSAVI<InputType,OutputType>()});
    m_Map.push_back({"list.msavi","Vegetation:MSAVI",new otb::Functor::MSAVI<InputType,OutputType>()});
    m_Map.push_back({"list.msavi2","Vegetation:MSAVI2",new otb::Functor::MSAVI2<InputType,OutputType>()});
    m_Map.push_back({"list.gemi","Vegetation:GEMI",new otb::Functor::GEMI<InputType,OutputType>()});
    m_Map.push_back({"list.ipvi","Vegetation:IPVI",new otb::Functor::IPVI<InputType,OutputType>()});
    m_Map.push_back({"list.laindvilog","Vegetation:LAIFromNDVILog",new otb::Functor::LAIFromNDVILogarithmic<InputType,OutputType>()});
    m_Map.push_back({"list.lairefl","Vegetation:LAIFromReflLinear",new otb::Functor::LAIFromReflectancesLinear<InputType,OutputType>()});
    m_Map.push_back({"list.laindviformo","Vegetation:LAIFromNDVIFormo",new otb::Functor::LAIFromNDVIFormosat2Functor<InputType,OutputType>()});
    m_Map.push_back({"list.ndwi","Water:NDWI",new otb::Functor::NDWI<InputType,OutputType>()});
    m_Map.push_back({"list.ndwi2","Water:NDWI2",new otb::Functor::NDWI2<InputType,OutputType>()});
    m_Map.push_back({"list.mndwi","Water:MNDWI",new otb::Functor::MNDWI<InputType,OutputType>()});
    m_Map.push_back({"list.ndti","Water:NDTI",new otb::Functor::NDTI<InputType,OutputType>()});
    m_Map.push_back({"list.si","Soil:RI",new otb::Functor::RI<InputType,OutputType>()});
    m_Map.push_back({"list.ci","Soil:CI",new otb::Functor::CI<InputType,OutputType>()});
    m_Map.push_back({"list.bi","Soil:BI",new otb::Functor::BI<InputType,OutputType>()});
    m_Map.push_back({"list.bi2","Soil:BI2",new otb::Functor::BI2<InputType,OutputType>()});

    ClearChoices("list");
    for ( unsigned int i=0; i<m_Map.size(); i++ )
      {
      AddChoice(m_Map[i].key, m_Map[i].item);
      }
  }

  // Compute required bands for selected indices
  std::set<CommonBandNames> GetRequiredBands()
  {
    std::set<CommonBandNames> required;

    for (unsigned int idx = 0; idx < GetSelectedItems("list").size(); ++idx)
        {
        auto requiredForCurrentIndice = m_Map[GetSelectedItems("list")[idx]].indice->GetRequiredBands();
        required.insert(requiredForCurrentIndice.begin(),requiredForCurrentIndice.end());
        }
    return required;
  }

  void DoUpdateParameters() override
  {
    //Nothing to do here
  }

  void DoExecute() override
  {
    // Retrieve number of bands of input image
    unsigned int nbChan = GetParameterImage("in")->GetNumberOfComponentsPerPixel();

    // Derive required bands from selected indices
    auto requiredBands = GetRequiredBands();

    // Map to store association between bands and indices
    std::map<CommonBandNames,size_t> bandIndicesMap;

    // Lambda that will:
    // - Check if band is required,
    // - Check band index range,
    // - Populate the bandIndicesMap
    auto bandChecker = [this,requiredBands, nbChan] (std::map<CommonBandNames, size_t> & indicesMap, const CommonBandNames& band, const std::string & key)
    {
      if(requiredBands.find(band) != requiredBands.end())
        {
          unsigned int idx = this->GetParameterInt(key);

          if(idx > nbChan)
            {
            otbAppLogFATAL(<<"Index for band "<<key<<" exceeds the number of channels in image ("<<nbChan<<")");
            }
          else
            {
              indicesMap[band] = idx-1;
            }
        }
    };

    // Call lambda for each possible band
    bandChecker(bandIndicesMap,CommonBandNames::BLUE,"channels.blue");
    bandChecker(bandIndicesMap,CommonBandNames::GREEN,"channels.green");
    bandChecker(bandIndicesMap,CommonBandNames::RED,"channels.red");
    bandChecker(bandIndicesMap,CommonBandNames::NIR,"channels.nir");
    bandChecker(bandIndicesMap,CommonBandNames::MIR,"channels.mir");

    std::vector<RadiometricIndiceType*> indices;

    // Find selected indices
    for(unsigned int idx = 0; idx < GetSelectedItems("list").size(); ++idx)
      {
      // Retrieve the indice instance
      indices.push_back(m_Map[GetSelectedItems("list")[idx]].indice.get());

      // And set bands using the band map
      indices.back()->SetBandsIndices(bandIndicesMap);
      }

    // Build a composite indices functor to compute all indices at
    // once
    auto compositeFunctor = IndicesStackFunctorType(indices);

    // Build and plug functor filter
    auto filter = NewFunctorFilter(compositeFunctor);
    filter->SetInputs(GetParameterImage("in"));
    SetParameterOutputImage("out", filter->GetOutput());

    // Call register pipeline to allow streaming and garbage collection
    RegisterPipeline();
  }

  std::vector<indiceSpec> m_Map;

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::RadiometricIndices)
<commit_msg>ENH: Add ISU to radiometric indices app<commit_after>/*
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
#include "otbWrapperNumericalParameter.h"

#include "otbVegetationIndicesFunctor.h"
#include "otbWaterIndicesFunctor.h"
#include "otbBuiltUpIndicesFunctor.h"
#include "otbSoilIndicesFunctor.h"
#include "otbIndicesStackFunctor.h"
#include "otbFunctorImageFilter.h"

namespace otb
{
namespace Wrapper
{

class RadiometricIndices: public Application
{
public:
  /** Standard class typedefs. */
  typedef RadiometricIndices       Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(RadiometricIndices, otb::Wrapper::Application);

  using InputType = FloatVectorImageType::InternalPixelType;
  using OutputType = FloatImageType::PixelType;

  using RadiometricIndiceType = otb::Functor::RadiometricIndice<InputType, OutputType>;
  using IndicesStackFunctorType = otb::Functor::IndicesStackFunctor<RadiometricIndiceType>;

  class indiceSpec
  {
  public:
    indiceSpec(std::string k, std::string i, RadiometricIndiceType * ind)
      : key(k), item(i), indice(ind)
    {}
    std::string key;
    std::string item;
    std::unique_ptr<RadiometricIndiceType> indice;
  };

private:
  void DoInit() override
  {
    SetName("RadiometricIndices");
    SetDescription("Compute radiometric indices.");

    // Documentation
    SetDocName("Radiometric Indices");
    SetDocLongDescription("This application computes radiometric indices using the relevant channels of the input image. The output is a multi band image into which each channel is one of the selected indices.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso("otbVegetationIndicesFunctor, otbWaterIndicesFunctor and otbSoilIndicesFunctor classes");

    AddDocTag(Tags::FeatureExtraction);
	AddDocTag("Radiometric Indices");

    AddParameter(ParameterType_InputImage, "in", "Input Image");
    SetParameterDescription("in", "Input image");

    AddParameter(ParameterType_OutputImage, "out", "Output Image");
    SetParameterDescription("out", "Radiometric indices output image");

    AddParameter(ParameterType_Group, "channels", "Channels selection");
    SetParameterDescription("channels", "Channels selection");

    AddParameter(ParameterType_Int,  "channels.blue",  "Blue Channel");
    SetParameterDescription("channels.blue", "Blue channel index");
    SetDefaultParameterInt("channels.blue", 1);
    AddParameter(ParameterType_Int,  "channels.green",  "Green Channel");
    SetParameterDescription("channels.green", "Green channel index");
    SetDefaultParameterInt("channels.green", 1);
    AddParameter(ParameterType_Int,  "channels.red",  "Red Channel");
    SetParameterDescription("channels.red", "Red channel index");
    SetDefaultParameterInt("channels.red", 1);
    AddParameter(ParameterType_Int,  "channels.nir",  "NIR Channel");
    SetParameterDescription("channels.nir", "NIR channel index");
    SetDefaultParameterInt("channels.nir", 1);
    AddParameter(ParameterType_Int,  "channels.mir",  "Mir Channel");
    SetParameterDescription("channels.mir", "Mir channel index");
    SetDefaultParameterInt("channels.mir", 1);

    AddParameter(ParameterType_ListView,  "list", "Available Radiometric Indices");
    SetParameterDescription("list",
        "List of available radiometric indices with their relevant channels in brackets:\n\n"
        "* Vegetation:NDVI - Normalized difference vegetation index (Red, NIR)\n"
        "* Vegetation:TNDVI - Transformed normalized difference vegetation index (Red, NIR)\n"
        "* Vegetation:RVI - Ratio vegetation index (Red, NIR)\n"
        "* Vegetation:SAVI - Soil adjusted vegetation index (Red, NIR)\n"
        "* Vegetation:TSAVI - Transformed soil adjusted vegetation index (Red, NIR)\n"
        "* Vegetation:MSAVI - Modified soil adjusted vegetation index (Red, NIR)\n"
        "* Vegetation:MSAVI2 - Modified soil adjusted vegetation index 2 (Red, NIR)\n"
        "* Vegetation:GEMI - Global environment monitoring index (Red, NIR)\n"
        "* Vegetation:IPVI - Infrared percentage vegetation index (Red, NIR)\n"
        "* Water:NDWI - Normalized difference water index (Gao 1996) (NIR, MIR)\n"
        "* Water:NDWI2 - Normalized difference water index (Mc Feeters 1996) (Green, NIR)\n"
        "* Water:MNDWI - Modified normalized difference water index (Xu 2006) (Green, MIR)\n"
        "* Water:NDTI - Normalized difference turbidity index (Lacaux et al.) (Red, Green)\n"
        "* Soil:RI - Redness index (Red, Green)\n"
        "* Soil:CI - Color index (Red, Green)\n"
        "* Soil:BI - Brightness index (Red, Green)\n"
        "* Soil:BI2 - Brightness index 2 (NIR, Red, Green)");

    AddRAMParameter();

    // Doc example parameter settings
    SetDocExampleParameterValue("in", "qb_RoadExtract.tif");
    SetDocExampleParameterValue("list", "Vegetation:NDVI Vegetation:RVI Vegetation:IPVI");
    SetDocExampleParameterValue("out", "RadiometricIndicesImage.tif");

    SetOfficialDocLink();

    m_Map.clear();

    m_Map.push_back({"list.ndvi","Vegetation:NDVI",new otb::Functor::NDVI<InputType,OutputType>()});
    m_Map.push_back({"list.tndvi","Vegetation:TNDVI",new otb::Functor::TNDVI<InputType,OutputType>()});
    m_Map.push_back({"list.rdvi","Vegetation:RVI",new otb::Functor::RVI<InputType,OutputType>()});
    m_Map.push_back({"list.savi","Vegetation:SAVI",new otb::Functor::SAVI<InputType,OutputType>()});
    m_Map.push_back({"list.tsavi","Vegetation:TSAVI",new otb::Functor::TSAVI<InputType,OutputType>()});
    m_Map.push_back({"list.msavi","Vegetation:MSAVI",new otb::Functor::MSAVI<InputType,OutputType>()});
    m_Map.push_back({"list.msavi2","Vegetation:MSAVI2",new otb::Functor::MSAVI2<InputType,OutputType>()});
    m_Map.push_back({"list.gemi","Vegetation:GEMI",new otb::Functor::GEMI<InputType,OutputType>()});
    m_Map.push_back({"list.ipvi","Vegetation:IPVI",new otb::Functor::IPVI<InputType,OutputType>()});
    m_Map.push_back({"list.laindvilog","Vegetation:LAIFromNDVILog",new otb::Functor::LAIFromNDVILogarithmic<InputType,OutputType>()});
    m_Map.push_back({"list.lairefl","Vegetation:LAIFromReflLinear",new otb::Functor::LAIFromReflectancesLinear<InputType,OutputType>()});
    m_Map.push_back({"list.laindviformo","Vegetation:LAIFromNDVIFormo",new otb::Functor::LAIFromNDVIFormosat2Functor<InputType,OutputType>()});
    m_Map.push_back({"list.ndwi","Water:NDWI",new otb::Functor::NDWI<InputType,OutputType>()});
    m_Map.push_back({"list.ndwi2","Water:NDWI2",new otb::Functor::NDWI2<InputType,OutputType>()});
    m_Map.push_back({"list.mndwi","Water:MNDWI",new otb::Functor::MNDWI<InputType,OutputType>()});
    m_Map.push_back({"list.ndti","Water:NDTI",new otb::Functor::NDTI<InputType,OutputType>()});
    m_Map.push_back({"list.ri","Soil:RI",new otb::Functor::RI<InputType,OutputType>()});
    m_Map.push_back({"list.ci","Soil:CI",new otb::Functor::CI<InputType,OutputType>()});
    m_Map.push_back({"list.bi","Soil:BI",new otb::Functor::BI<InputType,OutputType>()});
    m_Map.push_back({"list.bi2","Soil:BI2",new otb::Functor::BI2<InputType,OutputType>()});
    m_Map.push_back({"list.isu","BuiltUp:ISU",new otb::Functor::ISU<InputType,OutputType>()});
    ClearChoices("list");
    for ( unsigned int i=0; i<m_Map.size(); i++ )
      {
      AddChoice(m_Map[i].key, m_Map[i].item);
      }
  }

  // Compute required bands for selected indices
  std::set<CommonBandNames> GetRequiredBands()
  {
    std::set<CommonBandNames> required;

    for (unsigned int idx = 0; idx < GetSelectedItems("list").size(); ++idx)
        {
        auto requiredForCurrentIndice = m_Map[GetSelectedItems("list")[idx]].indice->GetRequiredBands();
        required.insert(requiredForCurrentIndice.begin(),requiredForCurrentIndice.end());
        }
    return required;
  }

  void DoUpdateParameters() override
  {
    //Nothing to do here
  }

  void DoExecute() override
  {
    // Retrieve number of bands of input image
    unsigned int nbChan = GetParameterImage("in")->GetNumberOfComponentsPerPixel();

    // Derive required bands from selected indices
    auto requiredBands = GetRequiredBands();

    // Map to store association between bands and indices
    std::map<CommonBandNames,size_t> bandIndicesMap;

    // Lambda that will:
    // - Check if band is required,
    // - Check band index range,
    // - Populate the bandIndicesMap
    auto bandChecker = [this,requiredBands, nbChan] (std::map<CommonBandNames, size_t> & indicesMap, const CommonBandNames& band, const std::string & key)
    {
      if(requiredBands.find(band) != requiredBands.end())
        {
          unsigned int idx = this->GetParameterInt(key);

          if(idx > nbChan)
            {
            otbAppLogFATAL(<<"Index for band "<<key<<" exceeds the number of channels in image ("<<nbChan<<")");
            }
          else
            {
              indicesMap[band] = idx-1;
            }
        }
    };

    // Call lambda for each possible band
    bandChecker(bandIndicesMap,CommonBandNames::BLUE,"channels.blue");
    bandChecker(bandIndicesMap,CommonBandNames::GREEN,"channels.green");
    bandChecker(bandIndicesMap,CommonBandNames::RED,"channels.red");
    bandChecker(bandIndicesMap,CommonBandNames::NIR,"channels.nir");
    bandChecker(bandIndicesMap,CommonBandNames::MIR,"channels.mir");

    std::vector<RadiometricIndiceType*> indices;

    // Find selected indices
    for(unsigned int idx = 0; idx < GetSelectedItems("list").size(); ++idx)
      {
      // Retrieve the indice instance
      indices.push_back(m_Map[GetSelectedItems("list")[idx]].indice.get());

      // And set bands using the band map
      indices.back()->SetBandsIndices(bandIndicesMap);
      }

    // Build a composite indices functor to compute all indices at
    // once
    auto compositeFunctor = IndicesStackFunctorType(indices);

    // Build and plug functor filter
    auto filter = NewFunctorFilter(compositeFunctor);
    filter->SetInputs(GetParameterImage("in"));
    SetParameterOutputImage("out", filter->GetOutput());

    // Call register pipeline to allow streaming and garbage collection
    RegisterPipeline();
  }

  std::vector<indiceSpec> m_Map;

};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::RadiometricIndices)
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <iostream>

#include "itkPeriodicBoundaryCondition.h"
#include "itkVectorImage.h"

using ImageType = itk::Image<int, 2>;
using RegionType = ImageType::RegionType;
using IndexType = ImageType::IndexType;
using SizeType = ImageType::SizeType;
using IteratorType = itk::ConstNeighborhoodIterator<ImageType>;
using RadiusType = IteratorType::RadiusType;

using VectorImageType = itk::VectorImage<int, 2>;
using VectorIteratorType = itk::ConstNeighborhoodIterator<VectorImageType>;

static bool
TestPrintNeighborhood(IteratorType & p, VectorIteratorType & v)
{
  bool success = true;

  std::cout << "Output from operator()(const OffsetType &, const OffsetType &, const NeighborhoodType *) const"
            << std::endl;
  unsigned x, y, i = 0;
  for (y = 0; y < p.GetSize()[1]; ++y)
  {
    for (x = 0; x < p.GetSize()[0]; ++x, ++i)
    {
      std::cout << p.GetPixel(i) << " ";
    }
    std::cout << std::endl;
  }

  std::cout << "Output from operator()(const OffsetType &, const OffsetType &, const NeighborhoodType *, "
            << "const NeighborhoodAccessorFunctorType &) const" << std::endl;

  i = 0;
  for (y = 0; y < v.GetSize()[1]; ++y)
  {
    for (x = 0; x < v.GetSize()[0]; ++x, ++i)
    {
      std::cout << v.GetPixel(i)[0] << " ";
    }
    std::cout << std::endl;
  }

  std::cout << "Ouptut from GetPixel( const IndexType & index, const TImage * image ) const" << std::endl;

  i = 0;
  for (y = 0; y < p.GetSize()[1]; ++y)
  {
    itk::Index<2> index;
    index[1] = p.GetIndex()[1] - p.GetRadius()[1] + y;
    for (x = 0; x < p.GetSize()[0]; ++x, ++i)
    {
      index[0] = p.GetIndex()[0] - p.GetRadius()[0] + x;

      // Access the pixel value through two different methods in the
      // boundary condition.
      int pixel1 = p.GetBoundaryCondition()->GetPixel(index, p.GetImagePointer());
      int pixel2 = p.GetPixel(i);

      std::cout << pixel1 << " ";

      // Check agreement of output from three three methods of accessing pixel values.
      if (pixel1 != pixel2)
      {
        success = false;
      }
    }
    std::cout << std::endl;
  }

  std::cout << "----" << std::endl;
  if (!success)
  {
    std::cerr << "Unexpected neighborhood value encountered in neighborhoods printed above." << std::endl;
  }

  return success;
}

static bool
CheckInputRequestedRegion(const RegionType & imageRegion,
                          const RegionType & requestedRegion,
                          const RegionType & expectedRegion)
{
  if (requestedRegion != expectedRegion)
  {
    std::cerr << "Unexpected input region for request region: " << std::endl;
    std::cerr << imageRegion << std::endl;
    std::cerr << "Got:" << std::endl;
    std::cerr << requestedRegion << std::endl;
    std::cerr << "Expected: " << std::endl;
    std::cerr << expectedRegion << std::endl;

    return false;
  }

  return true;
}

int
itkPeriodicBoundaryConditionTest(int, char *[])
{
  // Test an image to cover one operator() method.
  auto       image = ImageType::New();
  RegionType imageRegion;
  SizeType   imageSize = { { 5, 5 } };
  IndexType  imageIndex = { { 0, 0 } };
  imageRegion.SetSize(imageSize);
  imageRegion.SetIndex(imageIndex);
  image->SetRegions(imageRegion);
  image->Allocate();

  // Test a vector image to cover the other operator() method.
  auto vectorImage = VectorImageType::New();
  vectorImage->SetRegions(imageRegion);
  vectorImage->SetNumberOfComponentsPerPixel(1);
  vectorImage->Allocate();

  IndexType pos;
  for (pos[1] = 0; pos[1] < 5; ++pos[1])
  {
    for (pos[0] = 0; pos[0] < 5; ++pos[0])
    {
      image->SetPixel(pos, pos[0] * 10 + pos[1]);
      VectorImageType::PixelType vectorPixel(1);
      vectorPixel[0] = image->GetPixel(pos);
      vectorImage->SetPixel(pos, vectorPixel);
      std::cout << image->GetPixel(pos) << " ";
    }
    std::cout << std::endl;
  }

  RadiusType radius;
  RadiusType radiusTwo;
  radius[0] = radius[1] = 1;
  IteratorType       it(radius, image, image->GetRequestedRegion());
  VectorIteratorType vit(radius, vectorImage, vectorImage->GetRequestedRegion());

  itk::PeriodicBoundaryCondition<ImageType>       bc;
  itk::PeriodicBoundaryCondition<VectorImageType> vbc;

  it.OverrideBoundaryCondition(&bc);
  vit.OverrideBoundaryCondition(&vbc);

  pos[0] = pos[1] = 0;
  it.SetLocation(pos);

  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
  {
    std::cout << "Index: " << it.GetIndex() << std::endl;
    bool success = TestPrintNeighborhood(it, vit);
    if (!success)
    {
      return EXIT_FAILURE;
    }
  }

  radiusTwo[0] = radiusTwo[1] = 2;
  IteratorType       it2(radiusTwo, image, image->GetRequestedRegion());
  VectorIteratorType vit2(radiusTwo, vectorImage, vectorImage->GetRequestedRegion());

  it2.OverrideBoundaryCondition(&bc);
  vit2.OverrideBoundaryCondition(&vbc);

  pos[0] = pos[1] = 0;
  it2.SetLocation(pos);
  vit2.SetLocation(pos);

  for (it2.GoToBegin(); !it2.IsAtEnd(); ++it2)
  {
    std::cout << "Index: " << it2.GetIndex() << std::endl;
    bool success = TestPrintNeighborhood(it2, vit2);
    if (!success)
    {
      return EXIT_FAILURE;
    }
  }

  // Now test the input region calculation
  IndexType  requestIndex;
  SizeType   requestSize;
  RegionType requestRegion;

  IndexType  expectedIndex;
  SizeType   expectedSize;
  RegionType expectedRegion;

  RegionType inputRegion;

  // Test 1
  std::cout << "GetInputRequestedRegion() Test 1" << std::endl;
  requestIndex.Fill(0);
  requestSize.Fill(2);
  requestRegion.SetIndex(requestIndex);
  requestRegion.SetSize(requestSize);

  expectedRegion = requestRegion;

  inputRegion = bc.GetInputRequestedRegion(imageRegion, requestRegion);
  if (!CheckInputRequestedRegion(imageRegion, inputRegion, expectedRegion))
  {
    std::cerr << "[FAILED]" << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "[PASSED]" << std::endl;

  // Test 2
  std::cout << "GetInputRequestedRegion() Test 2" << std::endl;
  requestIndex[0] = -2;
  requestIndex[1] = 0;
  requestSize[0] = 3;
  requestSize[1] = 2;
  requestRegion.SetIndex(requestIndex);
  requestRegion.SetSize(requestSize);

  expectedIndex[0] = 0;
  expectedIndex[1] = 0;
  expectedSize[0] = 5;
  expectedSize[1] = 2;
  expectedRegion.SetIndex(expectedIndex);
  expectedRegion.SetSize(expectedSize);

  inputRegion = bc.GetInputRequestedRegion(imageRegion, requestRegion);
  if (!CheckInputRequestedRegion(imageRegion, inputRegion, expectedRegion))
  {
    std::cerr << "[FAILED]" << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "[PASSED]" << std::endl;

  // Test 3
  std::cout << "GetInputRequestedRegion() Test 3" << std::endl;
  requestIndex[0] = -2;
  requestIndex[1] = 8;
  requestSize[0] = 3;
  requestSize[1] = 3;
  requestRegion.SetIndex(requestIndex);
  requestRegion.SetSize(requestSize);

  expectedIndex[0] = 0;
  expectedIndex[1] = 0;
  expectedSize[0] = 5;
  expectedSize[1] = 5;
  expectedRegion.SetIndex(expectedIndex);
  expectedRegion.SetSize(expectedSize);

  inputRegion = bc.GetInputRequestedRegion(imageRegion, requestRegion);
  if (!CheckInputRequestedRegion(imageRegion, inputRegion, expectedRegion))
  {
    std::cerr << "[FAILED]" << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "[PASSED]" << std::endl;

  // Other boundary condition tests
  if (bc.RequiresCompleteNeighborhood() != true)
  {
    std::cerr << "RequiresCompleteNeighborhood() expected to return true, got false instead." << std::endl;
    return EXIT_FAILURE;
  }

  // Print boundary condition
  bc.Print(std::cout);
  vbc.Print(std::cout);

  // Check when ConstNeighborhoodIterator is templated over the
  // PeriodicBoundaryCondition
  auto                  testImage = ImageType::New();
  ImageType::SizeType   testSize = { { 64, 64 } };
  ImageType::RegionType testRegion(testSize);
  testImage->SetRegions(testRegion);
  testImage->Allocate();

  using BoundaryConditionType = itk::PeriodicBoundaryCondition<ImageType, ImageType>;
  using IterType = itk::ConstNeighborhoodIterator<ImageType, BoundaryConditionType>;
  IterType              testIter(radius, testImage, testRegion);
  BoundaryConditionType boundaryCondition;
  testIter.OverrideBoundaryCondition(&boundaryCondition);
  std::vector<IterType::OffsetType> back;
  back.push_back({ { -1, 0 } });
  back.push_back({ { 0, -1 } });
  back.push_back({ { 0, 0 } });
  testIter.SetNeedToUseBoundaryCondition(true);
  testIter.GoToBegin();
  float sum = 0.0f;
  while (!testIter.IsAtEnd())
  {
    for (auto & j : back)
    {
      const float d = testIter.GetPixel(j);
      sum += d;
    }
    ++testIter;
  }
  std::cout << "Dummy sum: " << sum << std::endl;

  return EXIT_SUCCESS;
}
<commit_msg>BUG: fix uninitialized memory warning in PeriodicBoundaryCondition test<commit_after>/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include <iostream>

#include "itkPeriodicBoundaryCondition.h"
#include "itkVectorImage.h"
#include "itkTestingMacros.h"

using ImageType = itk::Image<int, 2>;
using RegionType = ImageType::RegionType;
using IndexType = ImageType::IndexType;
using SizeType = ImageType::SizeType;
using IteratorType = itk::ConstNeighborhoodIterator<ImageType>;
using RadiusType = IteratorType::RadiusType;

using VectorImageType = itk::VectorImage<int, 2>;
using VectorIteratorType = itk::ConstNeighborhoodIterator<VectorImageType>;

static bool
TestPrintNeighborhood(IteratorType & p, VectorIteratorType & v)
{
  bool success = true;

  std::cout << "Output from operator()(const OffsetType &, const OffsetType &, const NeighborhoodType *) const"
            << std::endl;
  unsigned x, y, i = 0;
  for (y = 0; y < p.GetSize()[1]; ++y)
  {
    for (x = 0; x < p.GetSize()[0]; ++x, ++i)
    {
      std::cout << p.GetPixel(i) << " ";
    }
    std::cout << std::endl;
  }

  std::cout << "Output from operator()(const OffsetType &, const OffsetType &, const NeighborhoodType *, "
            << "const NeighborhoodAccessorFunctorType &) const" << std::endl;

  i = 0;
  for (y = 0; y < v.GetSize()[1]; ++y)
  {
    for (x = 0; x < v.GetSize()[0]; ++x, ++i)
    {
      std::cout << v.GetPixel(i)[0] << " ";
    }
    std::cout << std::endl;
  }

  std::cout << "Ouptut from GetPixel( const IndexType & index, const TImage * image ) const" << std::endl;

  i = 0;
  for (y = 0; y < p.GetSize()[1]; ++y)
  {
    itk::Index<2> index;
    index[1] = p.GetIndex()[1] - p.GetRadius()[1] + y;
    for (x = 0; x < p.GetSize()[0]; ++x, ++i)
    {
      index[0] = p.GetIndex()[0] - p.GetRadius()[0] + x;

      // Access the pixel value through two different methods in the
      // boundary condition.
      int pixel1 = p.GetBoundaryCondition()->GetPixel(index, p.GetImagePointer());
      int pixel2 = p.GetPixel(i);

      std::cout << pixel1 << " ";

      // Check agreement of output from three three methods of accessing pixel values.
      if (pixel1 != pixel2)
      {
        success = false;
      }
    }
    std::cout << std::endl;
  }

  std::cout << "----" << std::endl;
  if (!success)
  {
    std::cerr << "Unexpected neighborhood value encountered in neighborhoods printed above." << std::endl;
  }

  return success;
}

static bool
CheckInputRequestedRegion(const RegionType & imageRegion,
                          const RegionType & requestedRegion,
                          const RegionType & expectedRegion)
{
  if (requestedRegion != expectedRegion)
  {
    std::cerr << "Unexpected input region for request region: " << std::endl;
    std::cerr << imageRegion << std::endl;
    std::cerr << "Got:" << std::endl;
    std::cerr << requestedRegion << std::endl;
    std::cerr << "Expected: " << std::endl;
    std::cerr << expectedRegion << std::endl;

    return false;
  }

  return true;
}

int
itkPeriodicBoundaryConditionTest(int, char *[])
{
  // Test an image to cover one operator() method.
  auto       image = ImageType::New();
  RegionType imageRegion;
  SizeType   imageSize = { { 5, 5 } };
  IndexType  imageIndex = { { 0, 0 } };
  imageRegion.SetSize(imageSize);
  imageRegion.SetIndex(imageIndex);
  image->SetRegions(imageRegion);
  image->Allocate();

  // Test a vector image to cover the other operator() method.
  auto vectorImage = VectorImageType::New();
  vectorImage->SetRegions(imageRegion);
  vectorImage->SetNumberOfComponentsPerPixel(1);
  vectorImage->Allocate();

  IndexType pos;
  for (pos[1] = 0; pos[1] < 5; ++pos[1])
  {
    for (pos[0] = 0; pos[0] < 5; ++pos[0])
    {
      image->SetPixel(pos, pos[0] * 10 + pos[1]);
      VectorImageType::PixelType vectorPixel(1);
      vectorPixel[0] = image->GetPixel(pos);
      vectorImage->SetPixel(pos, vectorPixel);
      std::cout << image->GetPixel(pos) << " ";
    }
    std::cout << std::endl;
  }

  RadiusType radius;
  RadiusType radiusTwo;
  radius[0] = radius[1] = 1;
  IteratorType       it(radius, image, image->GetRequestedRegion());
  VectorIteratorType vit(radius, vectorImage, vectorImage->GetRequestedRegion());

  itk::PeriodicBoundaryCondition<ImageType>       bc;
  itk::PeriodicBoundaryCondition<VectorImageType> vbc;

  it.OverrideBoundaryCondition(&bc);
  vit.OverrideBoundaryCondition(&vbc);

  pos[0] = pos[1] = 0;
  it.SetLocation(pos);

  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
  {
    std::cout << "Index: " << it.GetIndex() << std::endl;
    bool success = TestPrintNeighborhood(it, vit);
    if (!success)
    {
      return EXIT_FAILURE;
    }
  }

  radiusTwo[0] = radiusTwo[1] = 2;
  IteratorType       it2(radiusTwo, image, image->GetRequestedRegion());
  VectorIteratorType vit2(radiusTwo, vectorImage, vectorImage->GetRequestedRegion());

  it2.OverrideBoundaryCondition(&bc);
  vit2.OverrideBoundaryCondition(&vbc);

  pos[0] = pos[1] = 0;
  it2.SetLocation(pos);
  vit2.SetLocation(pos);

  for (it2.GoToBegin(); !it2.IsAtEnd(); ++it2)
  {
    std::cout << "Index: " << it2.GetIndex() << std::endl;
    bool success = TestPrintNeighborhood(it2, vit2);
    if (!success)
    {
      return EXIT_FAILURE;
    }
  }

  // Now test the input region calculation
  IndexType  requestIndex;
  SizeType   requestSize;
  RegionType requestRegion;

  IndexType  expectedIndex;
  SizeType   expectedSize;
  RegionType expectedRegion;

  RegionType inputRegion;

  // Test 1
  std::cout << "GetInputRequestedRegion() Test 1" << std::endl;
  requestIndex.Fill(0);
  requestSize.Fill(2);
  requestRegion.SetIndex(requestIndex);
  requestRegion.SetSize(requestSize);

  expectedRegion = requestRegion;

  inputRegion = bc.GetInputRequestedRegion(imageRegion, requestRegion);
  if (!CheckInputRequestedRegion(imageRegion, inputRegion, expectedRegion))
  {
    std::cerr << "[FAILED]" << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "[PASSED]" << std::endl;

  // Test 2
  std::cout << "GetInputRequestedRegion() Test 2" << std::endl;
  requestIndex[0] = -2;
  requestIndex[1] = 0;
  requestSize[0] = 3;
  requestSize[1] = 2;
  requestRegion.SetIndex(requestIndex);
  requestRegion.SetSize(requestSize);

  expectedIndex[0] = 0;
  expectedIndex[1] = 0;
  expectedSize[0] = 5;
  expectedSize[1] = 2;
  expectedRegion.SetIndex(expectedIndex);
  expectedRegion.SetSize(expectedSize);

  inputRegion = bc.GetInputRequestedRegion(imageRegion, requestRegion);
  if (!CheckInputRequestedRegion(imageRegion, inputRegion, expectedRegion))
  {
    std::cerr << "[FAILED]" << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "[PASSED]" << std::endl;

  // Test 3
  std::cout << "GetInputRequestedRegion() Test 3" << std::endl;
  requestIndex[0] = -2;
  requestIndex[1] = 8;
  requestSize[0] = 3;
  requestSize[1] = 3;
  requestRegion.SetIndex(requestIndex);
  requestRegion.SetSize(requestSize);

  expectedIndex[0] = 0;
  expectedIndex[1] = 0;
  expectedSize[0] = 5;
  expectedSize[1] = 5;
  expectedRegion.SetIndex(expectedIndex);
  expectedRegion.SetSize(expectedSize);

  inputRegion = bc.GetInputRequestedRegion(imageRegion, requestRegion);
  if (!CheckInputRequestedRegion(imageRegion, inputRegion, expectedRegion))
  {
    std::cerr << "[FAILED]" << std::endl;
    return EXIT_FAILURE;
  }
  std::cout << "[PASSED]" << std::endl;

  // Other boundary condition tests
  if (bc.RequiresCompleteNeighborhood() != true)
  {
    std::cerr << "RequiresCompleteNeighborhood() expected to return true, got false instead." << std::endl;
    return EXIT_FAILURE;
  }

  // Print boundary condition
  bc.Print(std::cout);
  vbc.Print(std::cout);

  // Check when ConstNeighborhoodIterator is templated over the
  // PeriodicBoundaryCondition
  auto                  testImage = ImageType::New();
  ImageType::SizeType   testSize = { { 64, 64 } };
  ImageType::RegionType testRegion(testSize);
  testImage->SetRegions(testRegion);
  testImage->Allocate();
  testImage->FillBuffer(1);

  using BoundaryConditionType = itk::PeriodicBoundaryCondition<ImageType, ImageType>;
  using IterType = itk::ConstNeighborhoodIterator<ImageType, BoundaryConditionType>;
  IterType              testIter(radius, testImage, testRegion);
  BoundaryConditionType boundaryCondition;
  testIter.OverrideBoundaryCondition(&boundaryCondition);
  std::vector<IterType::OffsetType> back;
  back.push_back({ { -1, 0 } });
  back.push_back({ { 0, -1 } });
  back.push_back({ { 0, 0 } });
  testIter.SetNeedToUseBoundaryCondition(true);
  testIter.GoToBegin();
  float sum = 0.0f;
  while (!testIter.IsAtEnd())
  {
    for (auto & j : back)
    {
      const float d = testIter.GetPixel(j);
      sum += d;
    }
    ++testIter;
  }
  ITK_TEST_EXPECT_EQUAL(sum, testSize[0] * testSize[1] * 3);

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName      :    NFCLoginNet_ServerModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-01-02
//    @Module           :    NFCLoginNet_ServerModule
//    @Desc             :
// -------------------------------------------------------------------------

//#include "stdafx.h"
#include "NFCLoginNet_ServerModule.h"
#include "NFLoginNet_ServerPlugin.h"

const std::string PROPERTY_ACCOUNT = "Account";
const std::string PROPERTY_VERIFIED = "Verified";

bool NFCLoginNet_ServerModule::Init()
{
	return true;
}

bool NFCLoginNet_ServerModule::Shut()
{
	return true;
}

bool NFCLoginNet_ServerModule::BeforeShut()
{
	return true;
}

bool NFCLoginNet_ServerModule::AfterInit()
{

	m_pEventProcessModule = dynamic_cast<NFIEventProcessModule*>(pPluginManager->FindModule("NFCEventProcessModule"));
	m_pKernelModule = dynamic_cast<NFIKernelModule*>(pPluginManager->FindModule("NFCKernelModule"));
	m_pLoginLogicModule = dynamic_cast<NFILoginLogicModule*>(pPluginManager->FindModule("NFCLoginLogicModule"));
	m_pLogModule = dynamic_cast<NFILogModule*>(pPluginManager->FindModule("NFCLogModule"));
	m_pLogicClassModule = dynamic_cast<NFILogicClassModule*>(pPluginManager->FindModule("NFCLogicClassModule"));
    m_pElementInfoModule = dynamic_cast<NFIElementInfoModule*>(pPluginManager->FindModule("NFCElementInfoModule"));
    m_pLoginToMasterModule = dynamic_cast<NFILoginToMasterModule*>(pPluginManager->FindModule("NFCLoginToMasterModule"));
	m_pUUIDModule = dynamic_cast<NFIUUIDModule*>(pPluginManager->FindModule("NFCUUIDModule"));

	assert(NULL != m_pEventProcessModule);
	assert(NULL != m_pKernelModule);
	assert(NULL != m_pLoginLogicModule);
	assert(NULL != m_pLogModule);
	assert(NULL != m_pLogicClassModule);
    assert(NULL != m_pElementInfoModule);

	assert(NULL != m_pLoginToMasterModule);
	assert(NULL != m_pUUIDModule);

	m_pEventProcessModule->AddEventCallBack(NFIDENTID(), NFED_ON_CLIENT_LOGIN_RESULTS, this, &NFCLoginNet_ServerModule::OnLoginResultsEvent);
	m_pEventProcessModule->AddEventCallBack(NFIDENTID(), NFED_ON_CLIENT_SELECT_SERVER_RESULTS, this, &NFCLoginNet_ServerModule::OnSelectWorldResultsEvent);

	NF_SHARE_PTR<NFILogicClass> xLogicClass = m_pLogicClassModule->GetElement("Server");
	if (xLogicClass.get())
	{
		NFList<std::string>& xNameList = xLogicClass->GetConfigNameList();
		std::string strConfigName;
		for (bool bRet = xNameList.First(strConfigName); bRet; bRet = xNameList.Next(strConfigName))
		{
			const int nServerType = m_pElementInfoModule->GetPropertyInt(strConfigName, "Type");
            const int nServerID = m_pElementInfoModule->GetPropertyInt(strConfigName, "ServerID");
			if (nServerType == NF_SERVER_TYPES::NF_ST_LOGIN && pPluginManager->AppID() == nServerID)
			{
				const int nPort = m_pElementInfoModule->GetPropertyInt(strConfigName, "Port");
				const int nMaxConnect = m_pElementInfoModule->GetPropertyInt(strConfigName, "MaxOnline");
				const int nCpus = m_pElementInfoModule->GetPropertyInt(strConfigName, "CpuCount");

				m_pUUIDModule->SetIdentID(nServerID);

				Initialization(NFIMsgHead::NF_Head::NF_HEAD_LENGTH, this, &NFCLoginNet_ServerModule::OnReciveClientPack, &NFCLoginNet_ServerModule::OnSocketClientEvent, nMaxConnect, nPort, nCpus);
			}
		}
	}

	return true;
}

int NFCLoginNet_ServerModule::OnLoginResultsEvent(const NFIDENTID& object, const int nEventID, const NFIDataList& var)
{
	if (3 != var.GetCount()
		|| !var.TypeEx(TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_OBJECT, TDATA_TYPE::TDATA_STRING, TDATA_TYPE::TDATA_UNKNOWN))
	{
		return -1;
	}

	const int nState = var.Int(0);
	const NFIDENTID xIdent = var.Object(1);
	const std::string& strAccount = var.String(2);

	NF_SHARE_PTR<int> xFD = mxClientIdent.GetElement(xIdent);
	if (xFD)
	{
		if (0 != nState)
		{
			//ʺ߱
			//¼ʧ
			NFMsg::AckEventResult xMsg;
			xMsg.set_event_code(NFMsg::EGEC_ACCOUNTPWD_INVALID);

			SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_LOGIN, xMsg, *xFD);

			return 0;
		}

		NetObject* pNetObject = GetNet()->GetNetObject(*xFD);
		if (pNetObject)
		{
			//¼¼
			pNetObject->SetConnectKeyState(1);
			pNetObject->SetAccount(strAccount);
		}

		//ѷб㲥ȥ

		NFMsg::AckEventResult xData;
		xData.set_event_code(NFMsg::EGEC_ACCOUNT_SUCCESS);

		SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_LOGIN, xData, *xFD);

		//SynWorldToClient(unAddress);

		m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, *xFD), "Login successed :", strAccount.c_str());

	}

	return 0;
}

int NFCLoginNet_ServerModule::OnSelectWorldResultsEvent(const NFIDENTID& object, const int nEventID, const NFIDataList& var)
{
	if (7 != var.GetCount()
		|| !var.TypeEx(TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_OBJECT, TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_STRING,
		TDATA_TYPE::TDATA_STRING, TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_STRING, TDATA_TYPE::TDATA_UNKNOWN))
	{
		return -1;
	}

	const int nWorldID = var.Int(0);
	const NFIDENTID xClientIdent = var.Object(1);
	const int nLoginID = var.Int(2);
	const std::string& strAccount = var.String(3);
	const std::string& strWorldAddress = var.String(4);
	int nPort = var.Int(5);
	const std::string& strWorldKey = var.String(6);

	NF_SHARE_PTR<int> xFD = mxClientIdent.GetElement(xClientIdent);
	if (xFD)
	{
		NFMsg::AckConnectWorldResult xMsg;
		xMsg.set_world_id(nWorldID);
		xMsg.mutable_sender()->CopyFrom(NFToPB(xClientIdent));
		xMsg.set_login_id(nLoginID);
		xMsg.set_account(strAccount);
		xMsg.set_world_ip(strWorldAddress);
		xMsg.set_world_port(nPort);
		xMsg.set_world_key(strWorldKey);

		SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_CONNECT_WORLD, xMsg, *xFD);
	}

	return 0;
}

bool NFCLoginNet_ServerModule::Execute(const float fLasFrametime, const float fStartedTime)
{
	return NFINetModule::Execute(fLasFrametime, fStartedTime);
}

void NFCLoginNet_ServerModule::OnClientConnected(const int nAddress)
{
	NetObject* pObject = GetNet()->GetNetObject(nAddress);
	if (pObject)
	{
		NFIDENTID xIdent =m_pUUIDModule->CreateGUID();
		pObject->SetClientID(xIdent);
        mxClientIdent.AddElement(xIdent, NF_SHARE_PTR<int> (NF_NEW int(nAddress)) );
	}
}

void NFCLoginNet_ServerModule::OnClientDisconnect(const int nAddress)
{
	NetObject* pObject = GetNet()->GetNetObject(nAddress);
	if (pObject)
	{
		NFIDENTID xIdent = pObject->GetClientID();
		mxClientIdent.RemoveElement(xIdent);
	}
}

int NFCLoginNet_ServerModule::OnLoginProcess( const NFIPacket& msg )
{
	NFIDENTID nPlayerID;
	NFMsg::ReqAccountLogin xMsg;
	if (!RecivePB(msg, xMsg, nPlayerID))
	{
		return 0;
	}

    NetObject* pNetObject = GetNet()->GetNetObject(msg.GetFd());
    if (pNetObject)
    {
        //ûе¼
        if (pNetObject->GetConnectKeyState() == 0)
        {
            NFCDataList val;
            val << pNetObject->GetClientID()<< xMsg.account() << xMsg.password();
            m_pEventProcessModule->DoEvent(NFIDENTID(), NFED_ON_CLIENT_LOGIN, val);
        }
    }

	return 0;
}

int NFCLoginNet_ServerModule::OnSelectWorldProcess( const NFIPacket& msg )
{
	NFIDENTID nPlayerID;
	NFMsg::ReqConnectWorld xMsg;
	if (!RecivePB(msg, xMsg, nPlayerID))
	{
		return 0;
	}

	NetObject* pNetObject = GetNet()->GetNetObject(msg.GetFd());
	if (!pNetObject)
	{
		return 0;
	}

	//û¼
	if (pNetObject->GetConnectKeyState() <= 0)
	{
		return 0;
	}

	NFCDataList val;
	val << xMsg.world_id() << pNetObject->GetClientID() << pPluginManager->AppID() << pNetObject->GetAccount();
	m_pEventProcessModule->DoEvent(NFIDENTID(), NFED_ON_CLIENT_SELECT_SERVER, val);

	return 0;
}

int NFCLoginNet_ServerModule::OnReciveClientPack(const NFIPacket& msg )
{
	//ͳһ
	int nMsgID = msg.GetMsgHead()->GetMsgID();
	switch (nMsgID)
	{

	case NFMsg::EGameMsgID::EGMI_REQ_LOGIN:
		OnLoginProcess(msg);
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_LOGOUT:
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_CONNECT_WORLD:
		OnSelectWorldProcess(msg);
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_WORLD_LIST:
		OnViewWorldProcess(msg);
		break;

		// 	case NFMsg::EGameMsgID::EGMI_ACK_CONNECT_WORLD:
		// 		OnObjectPropertyIntProcess(msg);
		// 		break;

	default:
		printf("NFNet || ǷϢ:unMsgID=%d\n", nMsgID);
		break;
	}
	return 0;
}

int NFCLoginNet_ServerModule::OnSocketClientEvent( const int nSockIndex, const NF_NET_EVENT eEvent, NFINet* pNet )
{
    if (eEvent & NF_NET_EVENT_EOF)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_EOF", "Connection closed", __FUNCTION__, __LINE__);
        OnClientDisconnect(nSockIndex);
    }
    else if (eEvent & NF_NET_EVENT_ERROR)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_ERROR", "Got an error on the connection", __FUNCTION__, __LINE__);
        OnClientDisconnect(nSockIndex);
    }
    else if (eEvent & NF_NET_EVENT_TIMEOUT)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_TIMEOUT", "read timeout", __FUNCTION__, __LINE__);
        OnClientDisconnect(nSockIndex);
    }
    else  if (eEvent == NF_NET_EVENT_CONNECTED)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_CONNECTED", "connectioned success", __FUNCTION__, __LINE__);
        OnClientConnected(nSockIndex);
    }

	return 0;
}

void NFCLoginNet_ServerModule::SynWorldToClient( const int nFD )
{
    NFMsg::AckServerList xData;
    xData.set_type(NFMsg::RSLT_WORLD_SERVER);

    NFMapEx<int, NFMsg::ServerInfoReport>& xWorldMap = m_pLoginToMasterModule->GetWorldMap();
	NFMsg::ServerInfoReport* pWorldData =  xWorldMap.FirstNude();
	while (pWorldData)
	{
		NFMsg::ServerInfo* pServerInfo = xData.add_info();

		pServerInfo->set_name(pWorldData->server_name());
		pServerInfo->set_status(pWorldData->server_state());
		pServerInfo->set_server_id(pWorldData->server_id());
		pServerInfo->set_wait_count(0);

		pWorldData = xWorldMap.NextNude();
	}

    SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_WORLD_LIST, xData, nFD);
}

int NFCLoginNet_ServerModule::OnViewWorldProcess( const NFIPacket& msg )
{
	NFIDENTID nPlayerID;
	NFMsg::ReqServerList xMsg;
	if (!RecivePB(msg, xMsg, nPlayerID))
	{
		return 0;
	}

	if (xMsg.type() == NFMsg::RSLT_WORLD_SERVER)
	{
		SynWorldToClient(msg.GetFd());
	}

	return 0;
}

<commit_msg>handle heart beat msg<commit_after>// -------------------------------------------------------------------------
//    @FileName      :    NFCLoginNet_ServerModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-01-02
//    @Module           :    NFCLoginNet_ServerModule
//    @Desc             :
// -------------------------------------------------------------------------

//#include "stdafx.h"
#include "NFCLoginNet_ServerModule.h"
#include "NFLoginNet_ServerPlugin.h"

const std::string PROPERTY_ACCOUNT = "Account";
const std::string PROPERTY_VERIFIED = "Verified";

bool NFCLoginNet_ServerModule::Init()
{
	return true;
}

bool NFCLoginNet_ServerModule::Shut()
{
	return true;
}

bool NFCLoginNet_ServerModule::BeforeShut()
{
	return true;
}

bool NFCLoginNet_ServerModule::AfterInit()
{

	m_pEventProcessModule = dynamic_cast<NFIEventProcessModule*>(pPluginManager->FindModule("NFCEventProcessModule"));
	m_pKernelModule = dynamic_cast<NFIKernelModule*>(pPluginManager->FindModule("NFCKernelModule"));
	m_pLoginLogicModule = dynamic_cast<NFILoginLogicModule*>(pPluginManager->FindModule("NFCLoginLogicModule"));
	m_pLogModule = dynamic_cast<NFILogModule*>(pPluginManager->FindModule("NFCLogModule"));
	m_pLogicClassModule = dynamic_cast<NFILogicClassModule*>(pPluginManager->FindModule("NFCLogicClassModule"));
    m_pElementInfoModule = dynamic_cast<NFIElementInfoModule*>(pPluginManager->FindModule("NFCElementInfoModule"));
    m_pLoginToMasterModule = dynamic_cast<NFILoginToMasterModule*>(pPluginManager->FindModule("NFCLoginToMasterModule"));
	m_pUUIDModule = dynamic_cast<NFIUUIDModule*>(pPluginManager->FindModule("NFCUUIDModule"));

	assert(NULL != m_pEventProcessModule);
	assert(NULL != m_pKernelModule);
	assert(NULL != m_pLoginLogicModule);
	assert(NULL != m_pLogModule);
	assert(NULL != m_pLogicClassModule);
    assert(NULL != m_pElementInfoModule);

	assert(NULL != m_pLoginToMasterModule);
	assert(NULL != m_pUUIDModule);

	m_pEventProcessModule->AddEventCallBack(NFIDENTID(), NFED_ON_CLIENT_LOGIN_RESULTS, this, &NFCLoginNet_ServerModule::OnLoginResultsEvent);
	m_pEventProcessModule->AddEventCallBack(NFIDENTID(), NFED_ON_CLIENT_SELECT_SERVER_RESULTS, this, &NFCLoginNet_ServerModule::OnSelectWorldResultsEvent);

	NF_SHARE_PTR<NFILogicClass> xLogicClass = m_pLogicClassModule->GetElement("Server");
	if (xLogicClass.get())
	{
		NFList<std::string>& xNameList = xLogicClass->GetConfigNameList();
		std::string strConfigName;
		for (bool bRet = xNameList.First(strConfigName); bRet; bRet = xNameList.Next(strConfigName))
		{
			const int nServerType = m_pElementInfoModule->GetPropertyInt(strConfigName, "Type");
            const int nServerID = m_pElementInfoModule->GetPropertyInt(strConfigName, "ServerID");
			if (nServerType == NF_SERVER_TYPES::NF_ST_LOGIN && pPluginManager->AppID() == nServerID)
			{
				const int nPort = m_pElementInfoModule->GetPropertyInt(strConfigName, "Port");
				const int nMaxConnect = m_pElementInfoModule->GetPropertyInt(strConfigName, "MaxOnline");
				const int nCpus = m_pElementInfoModule->GetPropertyInt(strConfigName, "CpuCount");

				m_pUUIDModule->SetIdentID(nServerID);

				Initialization(NFIMsgHead::NF_Head::NF_HEAD_LENGTH, this, &NFCLoginNet_ServerModule::OnReciveClientPack, &NFCLoginNet_ServerModule::OnSocketClientEvent, nMaxConnect, nPort, nCpus);
			}
		}
	}

	return true;
}

int NFCLoginNet_ServerModule::OnLoginResultsEvent(const NFIDENTID& object, const int nEventID, const NFIDataList& var)
{
	if (3 != var.GetCount()
		|| !var.TypeEx(TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_OBJECT, TDATA_TYPE::TDATA_STRING, TDATA_TYPE::TDATA_UNKNOWN))
	{
		return -1;
	}

	const int nState = var.Int(0);
	const NFIDENTID xIdent = var.Object(1);
	const std::string& strAccount = var.String(2);

	NF_SHARE_PTR<int> xFD = mxClientIdent.GetElement(xIdent);
	if (xFD)
	{
		if (0 != nState)
		{
			//ʺ߱
			//¼ʧ
			NFMsg::AckEventResult xMsg;
			xMsg.set_event_code(NFMsg::EGEC_ACCOUNTPWD_INVALID);

			SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_LOGIN, xMsg, *xFD);

			return 0;
		}

		NetObject* pNetObject = GetNet()->GetNetObject(*xFD);
		if (pNetObject)
		{
			//¼¼
			pNetObject->SetConnectKeyState(1);
			pNetObject->SetAccount(strAccount);
		}

		//ѷб㲥ȥ

		NFMsg::AckEventResult xData;
		xData.set_event_code(NFMsg::EGEC_ACCOUNT_SUCCESS);

		SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_LOGIN, xData, *xFD);

		//SynWorldToClient(unAddress);

		m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, *xFD), "Login successed :", strAccount.c_str());

	}

	return 0;
}

int NFCLoginNet_ServerModule::OnSelectWorldResultsEvent(const NFIDENTID& object, const int nEventID, const NFIDataList& var)
{
	if (7 != var.GetCount()
		|| !var.TypeEx(TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_OBJECT, TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_STRING,
		TDATA_TYPE::TDATA_STRING, TDATA_TYPE::TDATA_INT, TDATA_TYPE::TDATA_STRING, TDATA_TYPE::TDATA_UNKNOWN))
	{
		return -1;
	}

	const int nWorldID = var.Int(0);
	const NFIDENTID xClientIdent = var.Object(1);
	const int nLoginID = var.Int(2);
	const std::string& strAccount = var.String(3);
	const std::string& strWorldAddress = var.String(4);
	int nPort = var.Int(5);
	const std::string& strWorldKey = var.String(6);

	NF_SHARE_PTR<int> xFD = mxClientIdent.GetElement(xClientIdent);
	if (xFD)
	{
		NFMsg::AckConnectWorldResult xMsg;
		xMsg.set_world_id(nWorldID);
		xMsg.mutable_sender()->CopyFrom(NFToPB(xClientIdent));
		xMsg.set_login_id(nLoginID);
		xMsg.set_account(strAccount);
		xMsg.set_world_ip(strWorldAddress);
		xMsg.set_world_port(nPort);
		xMsg.set_world_key(strWorldKey);

		SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_CONNECT_WORLD, xMsg, *xFD);
	}

	return 0;
}

bool NFCLoginNet_ServerModule::Execute(const float fLasFrametime, const float fStartedTime)
{
	return NFINetModule::Execute(fLasFrametime, fStartedTime);
}

void NFCLoginNet_ServerModule::OnClientConnected(const int nAddress)
{
	NetObject* pObject = GetNet()->GetNetObject(nAddress);
	if (pObject)
	{
		NFIDENTID xIdent =m_pUUIDModule->CreateGUID();
		pObject->SetClientID(xIdent);
        mxClientIdent.AddElement(xIdent, NF_SHARE_PTR<int> (NF_NEW int(nAddress)) );
	}
}

void NFCLoginNet_ServerModule::OnClientDisconnect(const int nAddress)
{
	NetObject* pObject = GetNet()->GetNetObject(nAddress);
	if (pObject)
	{
		NFIDENTID xIdent = pObject->GetClientID();
		mxClientIdent.RemoveElement(xIdent);
	}
}

int NFCLoginNet_ServerModule::OnLoginProcess( const NFIPacket& msg )
{
	NFIDENTID nPlayerID;
	NFMsg::ReqAccountLogin xMsg;
	if (!RecivePB(msg, xMsg, nPlayerID))
	{
		return 0;
	}

    NetObject* pNetObject = GetNet()->GetNetObject(msg.GetFd());
    if (pNetObject)
    {
        //ûе¼
        if (pNetObject->GetConnectKeyState() == 0)
        {
            NFCDataList val;
            val << pNetObject->GetClientID()<< xMsg.account() << xMsg.password();
            m_pEventProcessModule->DoEvent(NFIDENTID(), NFED_ON_CLIENT_LOGIN, val);
        }
    }

	return 0;
}

int NFCLoginNet_ServerModule::OnSelectWorldProcess( const NFIPacket& msg )
{
	NFIDENTID nPlayerID;
	NFMsg::ReqConnectWorld xMsg;
	if (!RecivePB(msg, xMsg, nPlayerID))
	{
		return 0;
	}

	NetObject* pNetObject = GetNet()->GetNetObject(msg.GetFd());
	if (!pNetObject)
	{
		return 0;
	}

	//û¼
	if (pNetObject->GetConnectKeyState() <= 0)
	{
		return 0;
	}

	NFCDataList val;
	val << xMsg.world_id() << pNetObject->GetClientID() << pPluginManager->AppID() << pNetObject->GetAccount();
	m_pEventProcessModule->DoEvent(NFIDENTID(), NFED_ON_CLIENT_SELECT_SERVER, val);

	return 0;
}

int NFCLoginNet_ServerModule::OnReciveClientPack(const NFIPacket& msg )
{
	//ͳһ
	int nMsgID = msg.GetMsgHead()->GetMsgID();
	switch (nMsgID)
	{
	case NFMsg::EGameMsgID::EGMI_STS_HEART_BEAT:
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_LOGIN:
		OnLoginProcess(msg);
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_LOGOUT:
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_CONNECT_WORLD:
		OnSelectWorldProcess(msg);
		break;

	case NFMsg::EGameMsgID::EGMI_REQ_WORLD_LIST:
		OnViewWorldProcess(msg);
		break;

		// 	case NFMsg::EGameMsgID::EGMI_ACK_CONNECT_WORLD:
		// 		OnObjectPropertyIntProcess(msg);
		// 		break;

	default:
		printf("NFNet || ǷϢ:unMsgID=%d\n", nMsgID);
		break;
	}
	return 0;
}

int NFCLoginNet_ServerModule::OnSocketClientEvent( const int nSockIndex, const NF_NET_EVENT eEvent, NFINet* pNet )
{
    if (eEvent & NF_NET_EVENT_EOF)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_EOF", "Connection closed", __FUNCTION__, __LINE__);
        OnClientDisconnect(nSockIndex);
    }
    else if (eEvent & NF_NET_EVENT_ERROR)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_ERROR", "Got an error on the connection", __FUNCTION__, __LINE__);
        OnClientDisconnect(nSockIndex);
    }
    else if (eEvent & NF_NET_EVENT_TIMEOUT)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_TIMEOUT", "read timeout", __FUNCTION__, __LINE__);
        OnClientDisconnect(nSockIndex);
    }
    else  if (eEvent == NF_NET_EVENT_CONNECTED)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFIDENTID(0, nSockIndex), "NF_NET_EVENT_CONNECTED", "connectioned success", __FUNCTION__, __LINE__);
        OnClientConnected(nSockIndex);
    }

	return 0;
}

void NFCLoginNet_ServerModule::SynWorldToClient( const int nFD )
{
    NFMsg::AckServerList xData;
    xData.set_type(NFMsg::RSLT_WORLD_SERVER);

    NFMapEx<int, NFMsg::ServerInfoReport>& xWorldMap = m_pLoginToMasterModule->GetWorldMap();
	NFMsg::ServerInfoReport* pWorldData =  xWorldMap.FirstNude();
	while (pWorldData)
	{
		NFMsg::ServerInfo* pServerInfo = xData.add_info();

		pServerInfo->set_name(pWorldData->server_name());
		pServerInfo->set_status(pWorldData->server_state());
		pServerInfo->set_server_id(pWorldData->server_id());
		pServerInfo->set_wait_count(0);

		pWorldData = xWorldMap.NextNude();
	}

    SendMsgPB(NFMsg::EGameMsgID::EGMI_ACK_WORLD_LIST, xData, nFD);
}

int NFCLoginNet_ServerModule::OnViewWorldProcess( const NFIPacket& msg )
{
	NFIDENTID nPlayerID;
	NFMsg::ReqServerList xMsg;
	if (!RecivePB(msg, xMsg, nPlayerID))
	{
		return 0;
	}

	if (xMsg.type() == NFMsg::RSLT_WORLD_SERVER)
	{
		SynWorldToClient(msg.GetFd());
	}

	return 0;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <set>
#include <unordered_map>

size_t size_of_longest_subseq(const std::string& s) {
  size_t max_seen = 0;
  auto tracker = std::set<char>();
  for (size_t i = 0; i < s.size(); ++i) {
    auto it = tracker.find(s[i]);
    if (it != tracker.end()) {
      // Found element -- need to start over
      if (tracker.size() > max_seen) {
        max_seen = tracker.size();
      }
    } else {
      tracker.insert(s[i]);
    }
  }
  // Check tracker size one last time
  if (tracker.size() > max_seen) {
    max_seen = tracker.size();
  }
  return max_seen;
}

void run_test_cases() {
  std::unordered_map<std::string, size_t> test_cases = {
    {"abab", 2},
    {"abc", 3},
    {"c", 1},
    {"abca", 3},
    {"ababc", 3},
    {"abcdaf", 5}
  };

  for (const auto& x : test_cases) {
    size_t actual = size_of_longest_subseq(x.first);
    size_t expected = x.second;
    std::string result = actual == expected ? "[PASS]" : "[FAIL]";
    std::cout << result << " Test case: " << x.first << '\n';
    std:: cout << "\tActual: " << actual << "\n\tExpected: " << expected << std::endl;
  }
}

int main(int argc, char* argv[]) {
  run_test_cases();
  return EXIT_SUCCESS;
}
<commit_msg>Adds empty string test case - algorithm still works<commit_after>#include <iostream>
#include <string>
#include <set>
#include <unordered_map>

size_t size_of_longest_subseq(const std::string& s) {
  size_t max_seen = 0;
  auto tracker = std::set<char>();
  for (size_t i = 0; i < s.size(); ++i) {
    auto it = tracker.find(s[i]);
    if (it != tracker.end()) {
      // Found element -- need to start over
      if (tracker.size() > max_seen) {
        max_seen = tracker.size();
      }
    } else {
      tracker.insert(s[i]);
    }
  }
  // Check tracker size one last time
  if (tracker.size() > max_seen) {
    max_seen = tracker.size();
  }
  return max_seen;
}

void run_test_cases() {
  std::unordered_map<std::string, size_t> test_cases = {
    {"abab", 2},
    {"abc", 3},
    {"c", 1},
    {"abca", 3},
    {"ababc", 3},
    {"abcdaf", 5},
    {"", 0}
  };

  for (const auto& x : test_cases) {
    size_t actual = size_of_longest_subseq(x.first);
    size_t expected = x.second;
    std::string result = actual == expected ? "[PASS]" : "[FAIL]";
    std::cout << result << " Test case: " << x.first << '\n';
    std:: cout << "\tActual: " << actual << "\n\tExpected: " << expected << std::endl;
  }
}

int main(int argc, char* argv[]) {
  run_test_cases();
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: facreg.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/dllapi.h"

#include <string.h>

#include <sal/config.h>

#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <cppuhelper/factory.hxx>
#include <uno/lbnames.h>

using namespace rtl;
using namespace com::sun::star;

#define SERVICE( className )                                        \
extern OUString SAL_CALL className##_getImplementationName() throw();   \
extern uno::Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw();\
extern uno::Reference< uno::XInterface > SAL_CALL className##_createInstance(           \
        const uno::Reference< lang::XMultiServiceFactory > & rSMgr )                \
    throw( uno::Exception )

namespace oox {
    namespace core { SERVICE( FilterDetect ); }
    namespace ppt { SERVICE( PowerPointImport ); }
    namespace xls { SERVICE( BiffDetector ); }
    namespace xls { SERVICE( ExcelFilter ); }
    namespace xls { SERVICE( ExcelBiffFilter ); }
    namespace shape { SERVICE( ShapeContextHandler ); }
    namespace shape { SERVICE( FastTokenHandlerService ); }
}

//
#ifdef __cplusplus
extern "C"
{
#endif

OOX_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

void SAL_CALL writeInfo( registry::XRegistryKey * pRegistryKey, const OUString& rImplementationName, const uno::Sequence< OUString >& rServices )
{
    uno::Reference< registry::XRegistryKey > xNewKey(
        pRegistryKey->createKey(
            OUString( sal_Unicode( '/' ) ) + rImplementationName + OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) ) );

    for( sal_Int32 i = 0; i < rServices.getLength(); i++ )
        xNewKey->createKey( rServices.getConstArray()[i]);
}

#define WRITEINFO(className)\
    writeInfo( pKey, className##_getImplementationName(), className##_getSupportedServiceNames() )

OOX_DLLPUBLIC sal_Bool SAL_CALL component_writeInfo( void * , void * pRegistryKey )
{
    if( pRegistryKey )
    {
        try
        {
            registry::XRegistryKey *pKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey );

            WRITEINFO( ::oox::core::FilterDetect );
            WRITEINFO( ::oox::ppt::PowerPointImport );
            WRITEINFO( ::oox::xls::BiffDetector );
            WRITEINFO( ::oox::xls::ExcelFilter );
            WRITEINFO( ::oox::xls::ExcelBiffFilter );
            WRITEINFO( ::oox::shape::ShapeContextHandler );
            WRITEINFO( ::oox::shape::FastTokenHandlerService );
        }
        catch (registry::InvalidRegistryException &)
        {
            OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
        }
    }
    return sal_True;
}

#define SINGLEFACTORY(classname)\
        if( classname##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) )\
        {\
            xFactory = ::cppu::createSingleFactory( xMSF,\
                classname##_getImplementationName(),\
                classname##_createInstance,\
                classname##_getSupportedServiceNames() );\
        }

OOX_DLLPUBLIC void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * )
{
    void * pRet = 0;
    if( pServiceManager )
    {
        uno::Reference< lang::XMultiServiceFactory > xMSF( reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) );

        uno::Reference< lang::XSingleServiceFactory > xFactory;

        const sal_Int32 nImplNameLen = strlen( pImplName );

        // impress oasis import
        SINGLEFACTORY( ::oox::core::FilterDetect )
        else SINGLEFACTORY( oox::ppt::PowerPointImport )
        else SINGLEFACTORY( ::oox::xls::BiffDetector )
        else SINGLEFACTORY( ::oox::xls::ExcelFilter )
        else SINGLEFACTORY( ::oox::xls::ExcelBiffFilter )
        else SINGLEFACTORY( ::oox::shape::ShapeContextHandler)
        else SINGLEFACTORY( ::oox::shape::FastTokenHandlerService)

        if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
    }
    return pRet;
}

#ifdef __cplusplus
}
#endif

<commit_msg>INTEGRATION: CWS xmlfilter05 (1.3.6); FILE MERGED 2008/05/09 08:44:25 os 1.3.6.1: i88938# import document properties - re-checkin<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: facreg.cxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#include "oox/dllapi.h"

#include <string.h>

#include <sal/config.h>

#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <cppuhelper/factory.hxx>
#include <uno/lbnames.h>

using namespace rtl;
using namespace com::sun::star;

#define SERVICE( className )                                        \
extern OUString SAL_CALL className##_getImplementationName() throw();   \
extern uno::Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw();\
extern uno::Reference< uno::XInterface > SAL_CALL className##_createInstance(           \
        const uno::Reference< lang::XMultiServiceFactory > & rSMgr )                \
    throw( uno::Exception )

#define SERVICE2( className )                                       \
extern OUString SAL_CALL className##_getImplementationName() throw();   \
extern uno::Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw();\
extern uno::Reference< uno::XInterface > SAL_CALL className##_createInstance(           \
        const uno::Reference< uno::XComponentContext > & xContext )             \
    throw( uno::Exception )

namespace oox {
    namespace core { SERVICE( FilterDetect ); }
    namespace ppt { SERVICE( PowerPointImport ); }
    namespace xls { SERVICE( BiffDetector ); }
    namespace xls { SERVICE( ExcelFilter ); }
    namespace xls { SERVICE( ExcelBiffFilter ); }
    namespace shape { SERVICE( ShapeContextHandler ); }
    namespace shape { SERVICE( FastTokenHandlerService ); }
    namespace docprop { SERVICE2( OOXMLDocPropImportImpl ); }
}

//
#ifdef __cplusplus
extern "C"
{
#endif

OOX_DLLPUBLIC void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

void SAL_CALL writeInfo( registry::XRegistryKey * pRegistryKey, const OUString& rImplementationName, const uno::Sequence< OUString >& rServices )
{
    uno::Reference< registry::XRegistryKey > xNewKey(
        pRegistryKey->createKey(
            OUString( sal_Unicode( '/' ) ) + rImplementationName + OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES") ) ) );

    for( sal_Int32 i = 0; i < rServices.getLength(); i++ )
        xNewKey->createKey( rServices.getConstArray()[i]);
}

#define WRITEINFO(className)\
    writeInfo( pKey, className##_getImplementationName(), className##_getSupportedServiceNames() )

OOX_DLLPUBLIC sal_Bool SAL_CALL component_writeInfo( void * , void * pRegistryKey )
{
    if( pRegistryKey )
    {
        try
        {
            registry::XRegistryKey *pKey = reinterpret_cast< registry::XRegistryKey * >( pRegistryKey );

            WRITEINFO( ::oox::core::FilterDetect );
            WRITEINFO( ::oox::ppt::PowerPointImport );
            WRITEINFO( ::oox::xls::BiffDetector );
            WRITEINFO( ::oox::xls::ExcelFilter );
            WRITEINFO( ::oox::xls::ExcelBiffFilter );
            WRITEINFO( ::oox::shape::ShapeContextHandler );
            WRITEINFO( ::oox::shape::FastTokenHandlerService );
            WRITEINFO( ::oox::docprop::OOXMLDocPropImportImpl );
        }
        catch (registry::InvalidRegistryException &)
        {
            OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
        }
    }
    return sal_True;
}

#define SINGLEFACTORY(classname)\
        if( classname##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) )\
        {\
            xFactory = ::cppu::createSingleFactory( xMSF,\
                classname##_getImplementationName(),\
                classname##_createInstance,\
                classname##_getSupportedServiceNames() );\
        }

#define SINGLEFACTORY2(classname)\
        if( classname##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) )\
        {\
            xCompFactory = ::cppu::createSingleComponentFactory(\
                classname##_createInstance,\
                classname##_getImplementationName(),\
                classname##_getSupportedServiceNames() );\
        }

OOX_DLLPUBLIC void * SAL_CALL component_getFactory( const sal_Char * pImplName, void * pServiceManager, void * )
{
    void * pRet = 0;
    if( pServiceManager )
    {
        uno::Reference< lang::XMultiServiceFactory > xMSF( reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) );

        uno::Reference< lang::XSingleServiceFactory > xFactory;
        uno::Reference< lang::XSingleComponentFactory > xCompFactory;

        const sal_Int32 nImplNameLen = strlen( pImplName );

        // impress oasis import
        SINGLEFACTORY( ::oox::core::FilterDetect )
        else SINGLEFACTORY( oox::ppt::PowerPointImport )
        else SINGLEFACTORY( ::oox::xls::BiffDetector )
        else SINGLEFACTORY( ::oox::xls::ExcelFilter )
        else SINGLEFACTORY( ::oox::xls::ExcelBiffFilter )
        else SINGLEFACTORY( ::oox::shape::ShapeContextHandler)
        else SINGLEFACTORY( ::oox::shape::FastTokenHandlerService)
        else SINGLEFACTORY2( ::oox::docprop::OOXMLDocPropImportImpl )

        if( xFactory.is())
        {
            xFactory->acquire();
            pRet = xFactory.get();
        }
        else if ( xCompFactory.is() )
        {
            xCompFactory->acquire();
            pRet = xCompFactory.get();
        }
    }
    return pRet;
}

#ifdef __cplusplus
}
#endif

<|endoftext|>