<commit_before>/*
GPE_Resources_Controller.cpp
This file is part of:
GAME PENCIL ENGINE
https://create.pawbyte.com
Copyright (c) 2014-2019 Nathan Hurde, Chase Lee.

Copyright (c) 2014-2019 PawByte LLC.
Copyright (c) 2014-2019 Game Pencil Engine contributors ( Contributors Page )

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-Game Pencil Engine <https://create.pawbyte.com>

*/

#include "GPE_Resources_Controller.h"

std::string RESOURCE_TYPE_NAMES[res_type_count];

generalGameResource::generalGameResource()
{
    isFullScreenResource = false;
    resourceName = "";
    resourceFileName = "";
    parentProjectName = "";
    parentProjectDirectory = "";
    globalResouceIdNumber = -1;
    subResouceId = -1;
    resourceType = -1;
    encapBox.x = 0;
    encapBox.y = 0;
    encapBox.w = 32;
    encapBox.h = 32;
    isModified = false;
    editorMode = 0;
    exportBuildGlobalId = -1;
    justOpenedThisFrame = false;
    requestedMode = editorMode = 0;
}

generalGameResource::~generalGameResource()
{

}

void generalGameResource::integrate_into_syntax()
{

}

std::string generalGameResource::get_current_name()
{
    return resourceName;
}

std::string generalGameResource::get_name()
{
    return resourceName;
}

int generalGameResource::get_global_rid()
{
    return globalResouceIdNumber;
}

bool generalGameResource::is_modified()
{
    return isModified;
}

bool generalGameResource::matches(generalGameResource * otherContainer)
{
    if( otherContainer!=NULL)
    {
        if( globalResouceIdNumber==otherContainer->globalResouceIdNumber)
        {
            if( resourceType== otherContainer->resourceType)
            {
                if( subResouceId==otherContainer->subResouceId)
                {
                    if( parentProjectName.compare(otherContainer->parentProjectName)==0)
                    {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

void generalGameResource::open_code( int lineNumb, int colNumb, std::string codeTitle )
{

}

void generalGameResource::preprocess_self(std::string alternatePath)
{

}

void generalGameResource::prerender_self( )
{

}

void generalGameResource::process_resource(GPE_Rect * viewedSpace,GPE_Rect *cam)
{
    process_self(viewedSpace,cam);
}

void generalGameResource::process_self(GPE_Rect * viewedSpace,GPE_Rect *cam)
{

}

void generalGameResource::render_resource(GPE_Rect * viewedSpace,GPE_Rect *cam, bool forceRedraw)
{
    viewedSpace = GPE_find_camera(viewedSpace);
    cam = GPE_find_camera(cam);
    if(cam!=NULL)
    {
        if( forceRedraw || justOpenedThisFrame )
        {
            //gcanvas->render_rectangle( 0,0,viewedSpace->w,viewedSpace->h,GPE_MAIN_THEME->Program_Color,false);
            forceRedraw = true;
        }
        render_self( viewedSpace,cam,forceRedraw);
    }
    justOpenedThisFrame = false;
}

void generalGameResource::render_self(GPE_Rect * viewedSpace,GPE_Rect *cam, bool forceRedraw)
{

}

void generalGameResource::save_resource(std::string alternatePath, int backupId)
{
    GPE_Report("Old save resource used..");
    isModified = false;
}

void generalGameResource::set_name(std::string newName)
{
    resourceName = newName;
}

void generalGameResource::set_parent_project(std::string newName)
{
    parentProjectName = newName;
}

void generalGameResource::set_global_rid(int newRId)
{
    globalResouceIdNumber = newRId;
}
void generalGameResource::update_box(int newX, int newY, int newW, int newH)
{
    if( newX!=-1)
    {
        encapBox.x = newX;
    }
    if(newY!=-1)
    {
        encapBox.y = newY;
    }

    if( newW!=-1)
    {
        encapBox.w = newW;
    }
    if(newH!=-1)
    {
        encapBox.h = newH;
    }
}

void generalGameResource::update_string(std::string newName)
{
    resourceName = newName;
}

bool generalGameResource::write_data_into_projectfile(std::ofstream * fileTarget, int nestedFoldersIn)
{
    return true;
}

int generalGameResource::search_for_string(std::string needle)
{
    return 0;
}

int generalGameResource::search_and_replace_string(std::string needle, std::string newStr )
{
    return 0;
}

bool generalGameResource::write_header_on_file(std::ofstream * fileTarget)
{
    if( fileTarget!=NULL && fileTarget->is_open() )
    {
        *fileTarget << "#    --------------------------------------------------  # \n";
        *fileTarget << "#     \n";
        *fileTarget << "#     \n";
        if( resourceType >=0 && resourceType < res_type_count)
        {
            *fileTarget << "#    Game Pencil Engine Project Game " << RESOURCE_TYPE_NAMES[resourceType] <<" DataFile \n";
        }
        *fileTarget << "#    Created automatically via the Game Pencil Engine Editor \n";
        *fileTarget << "#    Warning: Manually editing this file may cause unexpected bugs and errors. \n";
        *fileTarget << "#    If you have any problems reading this file please report it to help@pawbyte.com . \n";
        *fileTarget << "#     \n";
        *fileTarget << "#     \n";
        *fileTarget << "#    --------------------------------------------------  # \n";
        *fileTarget << "Version=" << GPE_VERSION_DOUBLE_NUMBER << "\n";
        *fileTarget << "ResourceName=" << resourceName << "\n";
        *fileTarget << "#     \n";
        return true;
    }
    return false;
}

GPE_DataManager::GPE_DataManager()
{
    randomVariableOn=false;
}

GPE_DataManager::~GPE_DataManager()
{
    randomVariableOn=false;
    //loops and deletes music
    clean_up();
}

//adds a new game sprite with one row
GPE_Animation* GPE_DataManager::sprite_add(std::string spriteFileName,int imgnumb,bool transparent,int xorig,int yorig, bool addMirror)
{
    GPE_Animation * newSprite = get_sprite(spriteFileName);
    if(newSprite!=NULL)
        return newSprite;
    //makes sure the xorig and yorig is not negative
    if(( xorig>=0)&&(yorig>=0) )
    {
        //GPE_Report("Loading "+spriteFileName+" sprite with "+int_to_string(imgnumb)+" needed images.");
        //loads in the sprite's texture
        newSprite = new GPE_Animation( spriteFileName, spriteFileName, transparent );
    }
    else
    {
        std::stringstream outString;
        outString << "Unable to load Sprite from file location: (" << spriteFileName << ") due to negative dimensions given";
        GPE_Report( outString.str());
        return NULL;
    }
}

GPE_Animation* GPE_DataManager::sprite_add_collision(std::string spriteFileName,int imgnumb,bool transparent,int xorig,int yorig, int cx, int cy, int cw, int ch, bool addMirror)
{
    GPE_Animation * newSprite = get_sprite(spriteFileName);
    if(newSprite!=NULL)
        return newSprite;
    //makes sure the xorig and yorig is not negative
    if(( xorig>=0)&&(yorig>=0) )
    {
        GPE_Report("Loading" +spriteFileName+" sprite...");
        //loads in the sprite's texture
        newSprite = new GPE_Animation(spriteFileName,spriteFileName, transparent);
        newSprite->edit_collision_box(cx, cy, cw, ch);
        return newSprite;
    }
    else
    {
        std::stringstream outString;
        outString << "Unable to load Sprite from file location: (" << spriteFileName << ") due to negative dimensions given";
        GPE_Report( outString.str());
        return NULL;
    }
}

GPE_Animation* GPE_DataManager::sprite_addsheet(std::string spriteFileName, bool transparent, int width, int height)
{
    GPE_Animation * newSprite = get_sprite(spriteFileName);
    if(newSprite!=NULL)
        return newSprite;
    if(( height>0)&&(width>0) )
    {
        newSprite = new GPE_Animation(spriteFileName,spriteFileName, transparent);
        return newSprite;
    }
    else
    {
        std::stringstream outString;
        outString << "Unable to load Sprite from file location: (" << spriteFileName << " due to negative dimensions given)";
        GPE_Report( outString.str());
        return NULL;
    }
}

GPE_Animation* GPE_DataManager::sprite_addsheet_ext(std::string spriteFileName, bool transparent, unsigned short imgnumb, unsigned short imgPerRow, unsigned short width, unsigned short height, unsigned short cellOffX, unsigned short cellOffY, unsigned short pixelOffX, unsigned short pixOffY, unsigned short hSep, unsigned short vSep)
{
    GPE_Animation * newSprite = get_sprite(spriteFileName);
    if(newSprite!=NULL)
        return newSprite;
    if(( height!=0)&&(width!=0) )
    {
        newSprite = new GPE_Animation(spriteFileName, spriteFileName, transparent);
        return newSprite;
    }
    else
    {
        std::stringstream outString;
        outString << "Unable to load Sprite from file location: (" << spriteFileName << " due to negative dimensions given)";
        GPE_Report( outString.str());
        return NULL;
    }
}

GPE_Texture* GPE_DataManager::texture_add(std::string textureFileName)
{
    GPE_Texture * newTexture = get_texture(textureFileName);
    if( newTexture!=NULL )
    {
        return newTexture;
    }
    else if( file_exists(textureFileName) )
    {
        //GPE_Report("Loading "+textureFileName+" texture image.");
        //loads in the sprite's texture
        newTexture = new GPE_Texture();
        if( newTexture!=NULL)
        {
            newTexture->load_new_texture( textureFileName, -1,true );
            if(newTexture->get_sdl_texture()!=NULL)
            {
                GPE_Report( "Texture_Add "+get_local_from_global_file( textureFileName )+ "["+int_to_string( (int)rTextures.size() )+"]");
                rTextures.push_back(newTexture);
                return newTexture;
            }
            else
            {
                delete newTexture;
                newTexture = NULL;
            }
        }
    }
    return NULL;
}

GPE_Animation * GPE_DataManager::get_sprite(int idIn)
{
    if( rAnimations.empty() )
        return NULL;
    if( (int)rAnimations.size()<idIn)
    {
        if (rAnimations.at(idIn) != NULL)
        {
            if(rAnimations.at(idIn)->animId == idIn)
            {
                return rAnimations.at(idIn);
            }
        }
    }
    for(int i=0; (int)i< (int)rAnimations.size(); i++)
    {
        if (rAnimations[i] != NULL)
        {
            if(rAnimations[i]->animId == idIn)
            {
                return rAnimations[i];
            }
        }
    }
    return NULL;
}

GPE_Animation* GPE_DataManager::get_sprite(std::string nameIn)
{
    if( rAnimations.empty() )
        return NULL;
    for(int i=0; i< (int)rAnimations.size(); i++)
    {
        if (rAnimations[i] != NULL)
        {
            if(rAnimations[i]->get_name()==nameIn || rAnimations[i]->get_file_name()==nameIn)
            {
                return rAnimations[i];
            }
        }
    }
    return NULL;
}

GPE_Texture* GPE_DataManager::get_texture(std::string textureFileName)
{
    GPE_Texture * tTexture = NULL;
    for(int i=0; i< (int)rTextures.size(); i++)
    {
        tTexture = rTextures[i];
        if ( tTexture!= NULL)
        {
            if(tTexture->get_filename() == textureFileName)
            {
                return tTexture;
            }
        }
    }
    return NULL;
}

GPE_Audio * GPE_DataManager::get_audio(int audioId)
{
    /*
    if( rAudio.empty() )
        return NULL;
    if( rAudio.size()<audioId  && audioId>=0)
    {
        if (rAudio.at(audioId) != NULL)
        {
            return audioId;
        }
    }
    for(int i=0;i<rAudio.size();i++)
    {
        if (rAudio[i] != NULL)
        {
            if(rAudio[i]->get_id() == audioId)
            {
                return i;
            }
        }
    }*/
    return NULL;
}

GPE_Audio * GPE_DataManager::get_audio(std::string nameIn)
{
    /*
    if( rSounds.empty() )
        return -1;
    for(int i=0;i<rSounds.size();i++)
    {
        if (rSounds[i] != NULL)
        {
            if(rSounds[i]->get_name()==nameIn || rSounds[i]->resourceFileName==nameIn)
            {
                return i;
            }
        }
    }*/
    return NULL;
}

GPE_Audio * GPE_DataManager::add_audio(std::string soundFileName, int soundTypeIn)
{
    GPE_Audio * returnVal = get_audio(soundFileName);
    /*
    if(returnVal>0)
    {
        return returnVal;
    }
    else
    {
        int prevSoundSize = (int)rSounds.size();

        Mix_Chunk* newSound = Mix_LoadWAV(soundFileName.c_str() );
        if(newSound!=NULL)
        {
            audioResource*  nSound = new audioResource();
            nSound->soundVal = newSound;
            nSound->fileName = soundFileName;
            nSound->name = getShortFileName(soundFileName);
            nSound->soundId = prevSoundSize;
            nSound->soundType = soundTypeIn;
            rSounds.push_back(nSound);
            if(prevSoundSize==(int)rSounds.size() )
            return (int)rSounds.size()-1;
        }
    }
    */
    return returnVal;
}

void GPE_DataManager::play_audio(int audioId, int loops)
{
    /*
    int fMusic = get_music(musicId);
    audioResource* pMusic = NULL;
    if(fMusic>=0 && fMusic < rMusic.size() )
    {
        pMusic  = rMusic.at(fMusic);
        if(pMusic!=NULL)
        {
            if(pMusic->musicVal!=NULL)
            {
                Mix_PlayMusic(pMusic->musicVal, loops );
            }
        }
    }
    */
}

void GPE_DataManager::remove_animation( GPE_Animation * anim )
{
    if( anim!=NULL && !rAnimations.empty() )
    {
        GPE_Animation * tAnim;
        for( int i= (int)rAnimations.size()-1; i>=0; i-- )
        {
            tAnim = rAnimations[i];
            if ( tAnim!= NULL)
            {
                if( tAnim->get_name()==anim->get_name() || tAnim->get_file_name()==anim->get_file_name() )
                {
                    delete tAnim;
                    tAnim = NULL;
                    rAnimations.erase( rAnimations.begin()+i );
                    return;
                }
            }
        }
    }
}

void GPE_DataManager::remove_texture( GPE_Texture * tex )
{
    if( tex!=NULL )
    {
        GPE_Texture * tTex;
        for( int i= (int)rTextures.size()-1; i>=0; i-- )
        {
            tTex = rTextures[i];
            if ( tTex!= NULL)
            {
                if( tTex->get_name()==tex->get_name() || tTex->get_filename()==tex->get_filename() )
                {
                    delete tTex;
                    tTex = NULL;
                    rTextures.erase( rTextures.begin()+i );
                }
            }
        }
    }
}

bool GPE_DataManager::load_files()
{
    //If everything loaded fine
    return true;
}

void GPE_DataManager::clean_up()
{
    int it;
    GPE_Animation * cAnimation = NULL;
    //loads through all of the sprites and deletes them
    for(int it=0; it<(int)rAnimations.size(); it++)
    {
        cAnimation = rAnimations[it];
        if( cAnimation!=NULL)
        {
            delete cAnimation;
            cAnimation = NULL;
        }
    }
    rAnimations.clear();

    if( (int)rTextures.size() >0 )
    {
        GPE_Texture * tTexure = NULL;
        for(it  = (int) rTextures.size()-1 ; it >=0; it-- )
        {
            tTexure = rTextures.at(it);
            if( tTexure!=NULL)
            {
                //GPE_Report( "Deleting Texture["+int_to_string( it )+"]" );
                delete tTexure;
                tTexure = NULL;
            }
        }
        rTextures.clear();
    }

    if( (int)rTilesheets.size() >0 )
    {
        GPE_Tilesheet * fTlesheet = NULL;
        for(it  = (int) rTilesheets.size()-1 ; it >=0; it-- )
        {
            fTlesheet = rTilesheets.at(it);
            if( fTlesheet!=NULL)
            {
                //GPE_Report( "Deleting Tilesheet["+int_to_string( it )+"]" );
                delete fTlesheet;
                fTlesheet = NULL;
            }
        }
        rTilesheets.clear();
    }

    if( (int)rAudio.size() >0 )
    {
        GPE_Audio * fAudio = NULL;
        for(it  = (int) rAudio.size()-1 ; it >=0; it-- )
        {
            fAudio = rAudio.at(it);
            if( fAudio!=NULL)
            {
                //GPE_Report( "Deleting Audio["+int_to_string( it )+"]" );
                delete fAudio;
                fAudio = NULL;
            }
        }
        rAudio.clear();
    }
}
<commit_msg>Delete GPE_Resources_Controller.cpp<commit_after><|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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 "itkCastImageFilter.h"
#include "itkRandomImageSource.h"
#include "itkVectorImage.h"
#include <iostream>
#include "itkFloatingPointExceptions.h"

// Better name demanging for gcc
#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 )
#ifndef __EMSCRIPTEN__
#define GCC_USEDEMANGLE
#endif
#endif

#ifdef GCC_USEDEMANGLE
#include <cstdlib>
#include <cxxabi.h>
#include "itkMath.h"
#endif

template< typename T >
std::string GetCastTypeName()
{
  std::string name;
#ifdef GCC_USEDEMANGLE
  char const *mangledName = typeid( T ).name();
  int         status;
  char *      unmangled = abi::__cxa_demangle(mangledName, nullptr, nullptr, &status);
  name = unmangled;
  free(unmangled);
#else
  name = typeid( T ).name();
#endif

  return name;
}

template < typename TInputPixelType, typename TOutputPixelType >
bool TestCastFromTo()
{
  using InputImageType = itk::Image< TInputPixelType, 3 >;
  using OutputImageType = itk::Image< TOutputPixelType, 3 >;
  using FilterType = itk::CastImageFilter< InputImageType, OutputImageType >;

  using SourceType = itk::RandomImageSource< InputImageType >;
  typename SourceType::Pointer source = SourceType::New();
  typename InputImageType::SizeValueType randomSize[3] = {18, 17, 23};
  source->SetSize( randomSize );

  source->UpdateLargestPossibleRegion();
  typename InputImageType::Pointer randomSourceImagePtr = source->GetOutput();
  {
    typename InputImageType::IndexType Index000 {0,0,0};
    typename InputImageType::IndexType Index100 {1,0,0};
    typename InputImageType::IndexType Index200 {2,0,0};
    typename InputImageType::IndexType Index300 {3,0,0};
    typename InputImageType::IndexType Index400 {4,0,0};

    /* Exercise input image type domain values (important for float -> integer conversions)
     *
     * Casting a float/double to an integer when integer isn't big enough to hold the value yields undefined behaviour.
     *
     * [n3290: 4.9/1]: A prvalue of a floating point type can be converted to a prvalue of an integer type.
     *  The conversion truncates; that is, the fractional part is discarded.
     *
     *  The behavior is undefined if the truncated value cannot be represented in the destination type.
     *                  ^^^^^^^^^
     * With scanline based optimization, SSE instructions can be used for converting blocks of
     * floats to integer, which results in different 'undefined' behavior for values
     * than an isolated static_cast<short>(outOfRangeFloat).
    */
    randomSourceImagePtr->SetPixel(Index000, std::numeric_limits<TInputPixelType>::max());
    randomSourceImagePtr->SetPixel(Index100, std::numeric_limits<TInputPixelType>::min());
    randomSourceImagePtr->SetPixel(Index200, std::numeric_limits<TInputPixelType>::epsilon() );
    randomSourceImagePtr->SetPixel(Index300, std::numeric_limits<TInputPixelType>::denorm_min() );
    randomSourceImagePtr->SetPixel(Index400, std::numeric_limits<TInputPixelType>::round_error() );
  }

  typename FilterType::Pointer filter = FilterType::New();
  filter->SetInput( randomSourceImagePtr );
  filter->UpdateLargestPossibleRegion();

  using InputIteratorType = itk::ImageRegionConstIterator< InputImageType >;
  using OutputIteratorType = itk::ImageRegionConstIterator< OutputImageType >;

  InputIteratorType  it( source->GetOutput(),
                         source->GetOutput()->GetLargestPossibleRegion() );
  OutputIteratorType ot( filter->GetOutput(),
                         filter->GetOutput()->GetLargestPossibleRegion() );

  bool success = true;

  std::cout << "Casting from " << GetCastTypeName< TInputPixelType >()
            << " to " << GetCastTypeName< TOutputPixelType >() << " ... ";

  it.GoToBegin();
  ot.GoToBegin();
  while ( !it.IsAtEnd() )
    {
    TInputPixelType  inValue  = it.Value();
    TOutputPixelType outValue = ot.Value();
    auto expectedValue = static_cast< TOutputPixelType >( inValue );

    if (std::is_floating_point<TInputPixelType>() && std::is_integral<TOutputPixelType>()
      && ( inValue > std::numeric_limits<TOutputPixelType>::max()
        || inValue < std::numeric_limits<TOutputPixelType>::min() )
      )
    {
      ++it;
      ++ot;
      std::cout << std::flush;
      //Debugging code left here for testing __MINGW32__ behavior below that may be redundant with this code
      //std::cout << "NOTICE: static_cast<" << GetCastTypeName< TOutputPixelType >() << ">(" << inValue << ") => "
      //         << outValue << " may not equal " << expectedValue
      //         << "  Casting out of range floating point values to integers is 'undefined' behavior."
      //         << std::flush << std::endl;
      continue;  // Simply skip the case where where the conversion is undefined.
    }

    /** Warning:
     * expectedValue == static_cast< TOutputPixelType( inValue ) is
     * false on some systems and compilers with some values of inValue. */
#if defined(__MINGW32__)  // NOTE:  This may be thee same problem identified above related to 'undefined' behavior
    if ( itk::Math::NotAlmostEquals(outValue, expectedValue) )
#else
    if ( itk::Math::NotExactlyEquals(outValue, expectedValue) )
#endif
      {
      std::cout << std::flush;
      std::cerr << "ERROR: staic_cast<" << GetCastTypeName< TOutputPixelType >() << ">(" << inValue << ") => "
                << outValue << " != " << expectedValue << std::flush << std::endl;
      success = false;
      break;
      }

    ++it;
    ++ot;
    }

  if ( success )
    {
    std::cout << "[PASSED]" << std::endl;
    }
  else
    {
    std::cout << "[FAILED]" << std::endl;
    }

  return success;
}

template < typename TInputPixelType >
bool TestCastFrom()
{
  bool success = true;
  success &= TestCastFromTo< TInputPixelType, char >();
  success &= TestCastFromTo< TInputPixelType, signed char >();
  success &= TestCastFromTo< TInputPixelType, unsigned char >();
  success &= TestCastFromTo< TInputPixelType, short >();
  success &= TestCastFromTo< TInputPixelType, unsigned short >();
  success &= TestCastFromTo< TInputPixelType, int >();
  success &= TestCastFromTo< TInputPixelType, unsigned int >();
  success &= TestCastFromTo< TInputPixelType, long >();
  success &= TestCastFromTo< TInputPixelType, unsigned long >();
  success &= TestCastFromTo< TInputPixelType, long long >();
  success &= TestCastFromTo< TInputPixelType, unsigned long long >();
  success &= TestCastFromTo< TInputPixelType, float >();
  success &= TestCastFromTo< TInputPixelType, double >();

  return success;
}

bool TestVectorImageCast()
{
  // This function casts a VectorImage<float, 2>
  // to a VectorImage<unsigned char, 2>
  std::cout << "Casting from a VectorImage<float, 2> \
                to VectorImage<unsigned char, 2> ..." << std::endl;

  using UnsignedCharVectorImageType = itk::VectorImage<unsigned char, 2>;
  using FloatVectorImageType = itk::VectorImage<float, 2>;

  // Create a 1x3 image of 2D vectors
  FloatVectorImageType::Pointer image = FloatVectorImageType::New();

  itk::Size<2> size;
  size[0] = 1;
  size[1] = 3;

  itk::Index<2> start;
  start.Fill(0);

  itk::ImageRegion<2> region(start,size);
  image->SetNumberOfComponentsPerPixel(2);
  image->SetRegions(region);
  image->Allocate();
  itk::VariableLengthVector<float> vec;
  vec.SetSize(2);
  // All pixels will be the vector (1.3, 5.3)
  vec[0] = 1.3;
  vec[1] = 5.3;
  image->FillBuffer(vec);

  using CastImageFilterType = itk::CastImageFilter< FloatVectorImageType,
               UnsignedCharVectorImageType >;
  CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New();
  castImageFilter->SetInput(image);
  castImageFilter->Update();

  // Setup iterators for the original and casted images
  itk::ImageRegionConstIterator<UnsignedCharVectorImageType>
       castedImageIterator(castImageFilter->GetOutput(),
       castImageFilter->GetOutput()->GetLargestPossibleRegion());

  itk::ImageRegionConstIterator<FloatVectorImageType>
    originalImageIterator(image, image->GetLargestPossibleRegion());

  // Compare both dimensions of all of the pixels from the manually
  // casted original image to the corresponding pixels in the filter-casted
  // image
  bool success = true;
  while(!originalImageIterator.IsAtEnd())
    {
    if(static_cast<unsigned char>(originalImageIterator.Get()[0]) !=
                                  castedImageIterator.Get()[0] ||
       static_cast<unsigned char>(originalImageIterator.Get()[1]) !=
                                  castedImageIterator.Get()[1])
      {
      std::cerr << "Error in TestVectorImageCast!" << std::endl;
      success = false;
      }
    ++originalImageIterator;
    ++castedImageIterator;
    }

  if ( success )
    {
    std::cout << "[PASSED]" << std::endl;
    }
  else
    {
    std::cout << "[FAILED]" << std::endl;
    }

  return success;
}

int itkCastImageFilterTest( int, char* [] )
{
  std::cout << "itkCastImageFilterTest Start" << std::endl;

  // This test casts floats to char, generating float point exceptions.
  // We disable float point exceptions only for this tests
  bool fpeSupport = itk::FloatingPointExceptions::HasFloatingPointExceptionsSupport();
  bool fpeStatus = itk::FloatingPointExceptions::GetEnabled();
  if (fpeSupport && fpeStatus)
    {
    std::cout << "FloatingPointExceptions are disabled only for this test." << std::endl;
    itk::FloatingPointExceptions::Disable();
    }

  bool success = true;
  success &= TestCastFrom< char >();
  success &= TestCastFrom< signed char >();
  success &= TestCastFrom< unsigned char >();
  success &= TestCastFrom< short >();
  success &= TestCastFrom< unsigned short >();
  success &= TestCastFrom< int >();
  success &= TestCastFrom< unsigned int >();
  success &= TestCastFrom< long >();
  success &= TestCastFrom< unsigned long >();
  success &= TestCastFrom< long long >();
  success &= TestCastFrom< unsigned long long >();
  success &= TestCastFrom< float >();
  success &= TestCastFrom< double >();
  success &= TestVectorImageCast();

  std::cout << std::endl;
  if ( !success )
    {
    std::cout << "An itkCastImageFilter test FAILED." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "All itkCastImageFilter tests PASSED." << std::endl;

  return EXIT_SUCCESS;
}
<commit_msg>STYLE: Minor variable naming and readability changes.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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 "itkCastImageFilter.h"
#include "itkRandomImageSource.h"
#include "itkVectorImage.h"
#include <iostream>
#include "itkFloatingPointExceptions.h"

// Better name demanging for gcc
#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ > 0 )
#ifndef __EMSCRIPTEN__
#define GCC_USEDEMANGLE
#endif
#endif

#ifdef GCC_USEDEMANGLE
#include <cstdlib>
#include <cxxabi.h>
#include "itkMath.h"
#endif

template< typename T >
std::string GetCastTypeName()
{
  std::string name;
#ifdef GCC_USEDEMANGLE
  char const *mangledName = typeid( T ).name();
  int         status;
  char *      unmangled = abi::__cxa_demangle(mangledName, nullptr, nullptr, &status);
  name = unmangled;
  free(unmangled);
#else
  name = typeid( T ).name();
#endif

  return name;
}

template < typename TInputPixelType, typename TOutputPixelType >
bool TestCastFromTo()
{
  using InputImageType = itk::Image< TInputPixelType, 3 >;
  using OutputImageType = itk::Image< TOutputPixelType, 3 >;
  using FilterType = itk::CastImageFilter< InputImageType, OutputImageType >;

  using SourceType = itk::RandomImageSource< InputImageType >;
  typename SourceType::Pointer randomValuesImageSource = SourceType::New();
  {
    typename InputImageType::SizeValueType randomSize[3] = {18, 17, 23};
    randomValuesImageSource->SetSize(randomSize);
  }
  randomValuesImageSource->UpdateLargestPossibleRegion();
  typename InputImageType::Pointer randomSourceImagePtr = randomValuesImageSource->GetOutput();
  {
    typename InputImageType::IndexType Index000{{0,0,0}};
    typename InputImageType::IndexType Index100{{1,0,0}};
    typename InputImageType::IndexType Index200{{2,0,0}};
    typename InputImageType::IndexType Index300{{3,0,0}};
    typename InputImageType::IndexType Index400{{4,0,0}};

    /* Exercise input image type domain values (important for float -> integer conversions)
     *
     * Casting a float/double to an integer when integer isn't big enough to hold the value yields undefined behaviour.
     *
     * [n3290: 4.9/1]: A prvalue of a floating point type can be converted to a prvalue of an integer type.
     *  The conversion truncates; that is, the fractional part is discarded.
     *
     *  The behavior is undefined if the truncated value cannot be represented in the destination type.
     *                  ^^^^^^^^^
     * With scanline based optimization, SSE instructions can be used for converting blocks of
     * floats to integer, which results in different 'undefined' behavior for values
     * than an isolated static_cast<short>(outOfRangeFloat).
    */
    randomSourceImagePtr->SetPixel(Index000, std::numeric_limits<TInputPixelType>::max());
    randomSourceImagePtr->SetPixel(Index100, std::numeric_limits<TInputPixelType>::min());
    randomSourceImagePtr->SetPixel(Index200, std::numeric_limits<TInputPixelType>::epsilon() );
    randomSourceImagePtr->SetPixel(Index300, std::numeric_limits<TInputPixelType>::denorm_min() );
    randomSourceImagePtr->SetPixel(Index400, std::numeric_limits<TInputPixelType>::round_error() );
  }

  typename FilterType::Pointer filter = FilterType::New();
  filter->SetInput( randomSourceImagePtr );
  filter->UpdateLargestPossibleRegion();

  using InputIteratorType = itk::ImageRegionConstIterator< InputImageType >;
  using OutputIteratorType = itk::ImageRegionConstIterator< OutputImageType >;

  InputIteratorType  it( randomValuesImageSource->GetOutput(),
                         randomValuesImageSource->GetOutput()->GetLargestPossibleRegion() );
  OutputIteratorType ot( filter->GetOutput(),
                         filter->GetOutput()->GetLargestPossibleRegion() );

  bool success = true;

  std::cout << "Casting from " << GetCastTypeName< TInputPixelType >()
            << " to " << GetCastTypeName< TOutputPixelType >() << " ... ";

  it.GoToBegin();
  ot.GoToBegin();
  while ( !it.IsAtEnd() )
    {
    const TInputPixelType  inValue  = it.Value();
    const TOutputPixelType outValue = ot.Value();

    const auto expectedValue = static_cast< TOutputPixelType >( inValue );

    if (std::is_floating_point<TInputPixelType>() && std::is_integral<TOutputPixelType>()
      && ( inValue > std::numeric_limits<TOutputPixelType>::max()
        || inValue < std::numeric_limits<TOutputPixelType>::min() )
      )
    {
      ++it;
      ++ot;
      std::cout << std::flush;
      //Debugging code left here for testing __MINGW32__ behavior below that may be redundant with this code
      //std::cout << "NOTICE: static_cast<" << GetCastTypeName< TOutputPixelType >() << ">(" << inValue << ") => "
      //         << outValue << " may not equal " << expectedValue
      //         << "  Casting out of range floating point values to integers is 'undefined' behavior."
      //         << std::flush << std::endl;
      continue;  // Simply skip the case where where the conversion is undefined.
    }

    /** Warning:
     * expectedValue == static_cast< TOutputPixelType( inValue ) is
     * false on some systems and compilers with some values of inValue. */
#if defined(__MINGW32__)  // NOTE:  This may be thee same problem identified above related to 'undefined' behavior
    if ( itk::Math::NotAlmostEquals(outValue, expectedValue) )
#else
    if ( itk::Math::NotExactlyEquals(outValue, expectedValue) )
#endif
      {
      std::cout << std::flush;
      std::cerr << "ERROR: staic_cast<" << GetCastTypeName< TOutputPixelType >() << ">(" << inValue << ") => "
                << outValue << " != " << expectedValue << std::flush << std::endl;
      success = false;
      break;
      }

    ++it;
    ++ot;
    }

  if ( success )
    {
    std::cout << "[PASSED]" << std::endl;
    }
  else
    {
    std::cout << "[FAILED]" << std::endl;
    }

  return success;
}

template < typename TInputPixelType >
bool TestCastFrom()
{
  bool success = true;
  success &= TestCastFromTo< TInputPixelType, char >();
  success &= TestCastFromTo< TInputPixelType, signed char >();
  success &= TestCastFromTo< TInputPixelType, unsigned char >();
  success &= TestCastFromTo< TInputPixelType, short >();
  success &= TestCastFromTo< TInputPixelType, unsigned short >();
  success &= TestCastFromTo< TInputPixelType, int >();
  success &= TestCastFromTo< TInputPixelType, unsigned int >();
  success &= TestCastFromTo< TInputPixelType, long >();
  success &= TestCastFromTo< TInputPixelType, unsigned long >();
  success &= TestCastFromTo< TInputPixelType, long long >();
  success &= TestCastFromTo< TInputPixelType, unsigned long long >();
  success &= TestCastFromTo< TInputPixelType, float >();
  success &= TestCastFromTo< TInputPixelType, double >();

  return success;
}

bool TestVectorImageCast()
{
  // This function casts a VectorImage<float, 2>
  // to a VectorImage<unsigned char, 2>
  std::cout << "Casting from a VectorImage<float, 2> \
                to VectorImage<unsigned char, 2> ..." << std::endl;

  using UnsignedCharVectorImageType = itk::VectorImage<unsigned char, 2>;
  using FloatVectorImageType = itk::VectorImage<float, 2>;

  // Create a 1x3 image of 2D vectors
  FloatVectorImageType::Pointer image = FloatVectorImageType::New();

  const itk::Size<2> size{ { 1, 3 } };
  const itk::Index<2> start{ { 0, 0 } };

  itk::ImageRegion<2> region(start,size);
  image->SetNumberOfComponentsPerPixel(2);
  image->SetRegions(region);
  image->Allocate();
  itk::VariableLengthVector<float> vec;
  vec.SetSize(2);
  // All pixels will be the vector (1.3, 5.3)
  vec[0] = 1.3;
  vec[1] = 5.3;
  image->FillBuffer(vec);

  using CastImageFilterType = itk::CastImageFilter< FloatVectorImageType,
               UnsignedCharVectorImageType >;
  CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New();
  castImageFilter->SetInput(image);
  castImageFilter->Update();

  // Setup iterators for the original and casted images
  itk::ImageRegionConstIterator<UnsignedCharVectorImageType>
       castedImageIterator(castImageFilter->GetOutput(),
       castImageFilter->GetOutput()->GetLargestPossibleRegion());

  itk::ImageRegionConstIterator<FloatVectorImageType>
    originalImageIterator(image, image->GetLargestPossibleRegion());

  // Compare both dimensions of all of the pixels from the manually
  // casted original image to the corresponding pixels in the filter-casted
  // image
  bool success = true;
  while(!originalImageIterator.IsAtEnd())
    {
    if(static_cast<unsigned char>(originalImageIterator.Get()[0]) !=
                                  castedImageIterator.Get()[0] ||
       static_cast<unsigned char>(originalImageIterator.Get()[1]) !=
                                  castedImageIterator.Get()[1])
      {
      std::cerr << "Error in TestVectorImageCast!" << std::endl;
      success = false;
      }
    ++originalImageIterator;
    ++castedImageIterator;
    }

  if ( success )
    {
    std::cout << "[PASSED]" << std::endl;
    }
  else
    {
    std::cout << "[FAILED]" << std::endl;
    }

  return success;
}

int itkCastImageFilterTest( int, char* [] )
{
  std::cout << "itkCastImageFilterTest Start" << std::endl;

  // This test casts floats to char, generating float point exceptions.
  // We disable float point exceptions only for this tests
  bool fpeSupport = itk::FloatingPointExceptions::HasFloatingPointExceptionsSupport();
  bool fpeStatus = itk::FloatingPointExceptions::GetEnabled();
  if (fpeSupport && fpeStatus)
    {
    std::cout << "FloatingPointExceptions are disabled only for this test." << std::endl;
    itk::FloatingPointExceptions::Disable();
    }

  bool success = true;
  success &= TestCastFrom< char >();
  success &= TestCastFrom< signed char >();
  success &= TestCastFrom< unsigned char >();
  success &= TestCastFrom< short >();
  success &= TestCastFrom< unsigned short >();
  success &= TestCastFrom< int >();
  success &= TestCastFrom< unsigned int >();
  success &= TestCastFrom< long >();
  success &= TestCastFrom< unsigned long >();
  success &= TestCastFrom< long long >();
  success &= TestCastFrom< unsigned long long >();
  success &= TestCastFrom< float >();
  success &= TestCastFrom< double >();
  success &= TestVectorImageCast();

  std::cout << std::endl;
  if ( !success )
    {
    std::cout << "An itkCastImageFilter test FAILED." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "All itkCastImageFilter tests PASSED." << std::endl;

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cCriticalSection:

cCriticalSection::cCriticalSection()
{
#ifdef _WIN32
	m_CriticalSectionPtr = new CRITICAL_SECTION;
	InitializeCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
#else
	m_Attributes = new pthread_mutexattr_t;
	pthread_mutexattr_init((pthread_mutexattr_t*)m_Attributes);
	pthread_mutexattr_settype((pthread_mutexattr_t*)m_Attributes, PTHREAD_MUTEX_RECURSIVE);

    m_CriticalSectionPtr = new pthread_mutex_t;
    if( pthread_mutex_init( (pthread_mutex_t*)m_CriticalSectionPtr, (pthread_mutexattr_t*)m_Attributes ) != 0 )
    {
        LOG("ERROR: Could not initialize Critical Section!");
    }
#endif
}

cCriticalSection::~cCriticalSection()
{
#ifdef _WIN32
	DeleteCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
	delete (CRITICAL_SECTION*)m_CriticalSectionPtr;
#else
    if( pthread_mutex_destroy( (pthread_mutex_t*)m_CriticalSectionPtr ) != 0 )
    {
        LOG("ERROR: Could not destroy Critical Section!");
    }
    delete (pthread_mutex_t*)m_CriticalSectionPtr;
	pthread_mutexattr_destroy( (pthread_mutexattr_t*)m_Attributes );
	delete (pthread_mutexattr_t*)m_Attributes;
#endif
}

void cCriticalSection::Lock()
{
#ifdef _WIN32
	EnterCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
#else
    pthread_mutex_lock( (pthread_mutex_t*)m_CriticalSectionPtr );
#endif
}

void cCriticalSection::Unlock()
{
#ifdef _WIN32
	LeaveCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
#else
    pthread_mutex_unlock( (pthread_mutex_t*)m_CriticalSectionPtr );
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cCSLock

cCSLock::cCSLock(cCriticalSection * a_CS) :
	m_CS(a_CS),
	m_IsLocked(false)
{
	Lock();
}

cCSLock::~cCSLock()
{
	Unlock();
}

void cCSLock::Lock(void)
{
	#ifdef _DEBUG
	assert(!m_IsLocked);
	m_IsLocked = true;
	#endif  // _DEBUG

	m_CS->Lock();
}

void cCSLock::Unlock(void)
{
	#ifdef _DEBUG
	assert(m_IsLocked);
	m_IsLocked = false;
	#endif  // _DEBUG

	m_CS->Unlock();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cCSUnlock:

cCSUnlock::cCSUnlock(cCSLock & a_Lock) :
	m_Lock(a_Lock)
{
	m_Lock.Unlock();
}

cCSUnlock::~cCSUnlock()
{
	m_Lock.Lock();
}

<commit_msg>Added missing #ifdef _DEBUG in cCriticalSection.cpp  Should compile in Release and on Linux now<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cCriticalSection:

cCriticalSection::cCriticalSection()
{
#ifdef _WIN32
	m_CriticalSectionPtr = new CRITICAL_SECTION;
	InitializeCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
#else
	m_Attributes = new pthread_mutexattr_t;
	pthread_mutexattr_init((pthread_mutexattr_t*)m_Attributes);
	pthread_mutexattr_settype((pthread_mutexattr_t*)m_Attributes, PTHREAD_MUTEX_RECURSIVE);

    m_CriticalSectionPtr = new pthread_mutex_t;
    if( pthread_mutex_init( (pthread_mutex_t*)m_CriticalSectionPtr, (pthread_mutexattr_t*)m_Attributes ) != 0 )
    {
        LOG("ERROR: Could not initialize Critical Section!");
    }
#endif
}

cCriticalSection::~cCriticalSection()
{
#ifdef _WIN32
	DeleteCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
	delete (CRITICAL_SECTION*)m_CriticalSectionPtr;
#else
    if( pthread_mutex_destroy( (pthread_mutex_t*)m_CriticalSectionPtr ) != 0 )
    {
        LOG("ERROR: Could not destroy Critical Section!");
    }
    delete (pthread_mutex_t*)m_CriticalSectionPtr;
	pthread_mutexattr_destroy( (pthread_mutexattr_t*)m_Attributes );
	delete (pthread_mutexattr_t*)m_Attributes;
#endif
}

void cCriticalSection::Lock()
{
#ifdef _WIN32
	EnterCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
#else
    pthread_mutex_lock( (pthread_mutex_t*)m_CriticalSectionPtr );
#endif
}

void cCriticalSection::Unlock()
{
#ifdef _WIN32
	LeaveCriticalSection( (CRITICAL_SECTION*)m_CriticalSectionPtr );
#else
    pthread_mutex_unlock( (pthread_mutex_t*)m_CriticalSectionPtr );
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cCSLock

cCSLock::cCSLock(cCriticalSection * a_CS)
	: m_CS(a_CS)
	#ifdef _DEBUG
	, m_IsLocked(false)
	#endif
{
	Lock();
}

cCSLock::~cCSLock()
{
	Unlock();
}

void cCSLock::Lock(void)
{
	#ifdef _DEBUG
	assert(!m_IsLocked);
	m_IsLocked = true;
	#endif  // _DEBUG

	m_CS->Lock();
}

void cCSLock::Unlock(void)
{
	#ifdef _DEBUG
	assert(m_IsLocked);
	m_IsLocked = false;
	#endif  // _DEBUG

	m_CS->Unlock();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cCSUnlock:

cCSUnlock::cCSUnlock(cCSLock & a_Lock) :
	m_Lock(a_Lock)
{
	m_Lock.Unlock();
}

cCSUnlock::~cCSUnlock()
{
	m_Lock.Lock();
}

<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: postgis.cc 44 2005-04-22 18:53:54Z pavlenko $

// mapnik
#include "connection_manager.hpp"
#include "postgis.hpp"
#include <mapnik/ptree_helpers.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>

// stl
#include <string>
#include <algorithm>
#include <set>
#include <sstream>
#include <iomanip>

DATASOURCE_PLUGIN(postgis_datasource)

const std::string postgis_datasource::GEOMETRY_COLUMNS="geometry_columns";
const std::string postgis_datasource::SPATIAL_REF_SYS="spatial_ref_system";

using std::clog;
using std::endl;

using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::shared_ptr;

using mapnik::PoolGuard;
using mapnik::attribute_descriptor;

postgis_datasource::postgis_datasource(parameters const& params)
   : datasource (params),
     table_(*params.get<std::string>("table","")),
     geometry_field_(*params.get<std::string>("geometry_field","")),
     cursor_fetch_size_(*params_.get<int>("cursor_size",0)),
     row_limit_(*params_.get<int>("row_limit",0)),
     type_(datasource::Vector),
     extent_initialized_(false),
     desc_(*params.get<std::string>("type"),"utf-8"),
     creator_(params.get<std::string>("host"),
              params.get<std::string>("port"),
              params.get<std::string>("dbname"),
              params.get<std::string>("user"),
              params.get<std::string>("password"))
{

   boost::optional<int> initial_size = params_.get<int>("inital_size",1);
   boost::optional<int> max_size = params_.get<int>("max_size",10);

   multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);

   boost::optional<std::string> ext  = params_.get<std::string>("extent");
   if (ext)
   {
      boost::char_separator<char> sep(",");
      boost::tokenizer<boost::char_separator<char> > tok(*ext,sep);
      unsigned i = 0;
      bool success = false;
      double d[4];
      for (boost::tokenizer<boost::char_separator<char> >::iterator beg=tok.begin();
           beg!=tok.end();++beg)
      {
         try
         {
             d[i] = boost::lexical_cast<double>(*beg);
         }
         catch (boost::bad_lexical_cast & ex)
         {
            std::clog << ex.what() << "\n";
            break;
         }
         if (i==3)
         {
            success = true;
            break;
         }
         ++i;
      }
      if (success)
      {
         extent_.init(d[0],d[1],d[2],d[3]);
         extent_initialized_ = true;
      }
   }

   ConnectionManager *mgr=ConnectionManager::instance();
   mgr->registerPool(creator_, *initial_size, *max_size);

   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,
            shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);

         desc_.set_encoding(conn->client_encoding());

         std::string table_name=table_from_sql(table_);
         std::string schema_name="";
         std::string::size_type idx=table_name.find_last_of('.');
         if (idx!=std::string::npos)
         {
            schema_name=table_name.substr(0,idx);
            table_name=table_name.substr(idx+1);
         }
         else
         {
            table_name=table_name.substr(0);
         }

         std::ostringstream s;
         s << "select f_geometry_column,srid,type from ";
         s << GEOMETRY_COLUMNS <<" where f_table_name='" << table_name<<"'";

         if (schema_name.length() > 0)
            s <<" and f_table_schema='"<< schema_name <<"'";

         if (geometry_field_.length() > 0)
            s << " and f_geometry_column = '" << geometry_field_ << "'";

         shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
         if (rs->next())
         {
            try
            {
               srid_ = lexical_cast<int>(rs->getValue("srid"));
            }
            catch (bad_lexical_cast &ex)
            {
               clog << ex.what() << endl;
            }
            geometryColumn_=rs->getValue("f_geometry_column");
            std::string postgisType=rs->getValue("type");
         }
         rs->close();

         // collect attribute desc
         s.str("");
         s << "select * from " << table_ << " limit 0";
         rs=conn->executeQuery(s.str());
         int count = rs->getNumFields();
         for (int i=0;i<count;++i)
         {
            std::string fld_name=rs->getFieldName(i);
            int type_oid = rs->getTypeOID(i);
            switch (type_oid)
            {
               case 21:    // int2
               case 23:    // int4
                  desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
                  break;
               case 700:   // float4
               case 701:   // float8
               case 1700:  // numeric ??
                  desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
               case 1042:  // bpchar
               case 1043:  // varchar
               case 25:    // text
                  desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
                  break;
               default: // shouldn't get here
#ifdef MAPNIK_DEBUG
                  clog << "unknown type_oid="<<type_oid<<endl;
#endif
                  break;
            }
         }
      }
   }
}

std::string const postgis_datasource::name_="postgis";

std::string postgis_datasource::name()
{
   return name_;
}

int postgis_datasource::type() const
{
   return type_;
}

layer_descriptor postgis_datasource::get_descriptor() const
{
   return desc_;
}

std::string postgis_datasource::table_from_sql(const std::string& sql)
{
   std::string table_name = boost::algorithm::to_lower_copy(sql);
   boost::algorithm::replace_all(table_name,"\n"," ");

   std::string::size_type idx = table_name.rfind("from");
   if (idx!=std::string::npos)
   {

      idx=table_name.find_first_not_of(" ",idx+4);
      if (idx != std::string::npos)
      {
         table_name=table_name.substr(idx);
      }
      idx=table_name.find_first_of(" )");
      if (idx != std::string::npos)
      {
         table_name = table_name.substr(0,idx);
      }
   }
   return table_name;
}

boost::shared_ptr<IResultSet> postgis_datasource::get_resultset(boost::shared_ptr<Connection> const &conn, const std::string &sql) const
{
     if (cursor_fetch_size_ > 0) {
         // cursor
         std::ostringstream csql;
         std::string cursor_name = conn->new_cursor_name();

         csql << "DECLARE " << cursor_name << " BINARY INSENSITIVE NO SCROLL CURSOR WITH HOLD FOR " << sql << " FOR READ ONLY";

#ifdef MAPNIK_DEBUG
         std::clog << csql.str() << "\n";
#endif
         if (!conn->execute(csql.str())) {
            throw mapnik::datasource_exception( "PSQL Error: Creating cursor for data select." );
         }
         return shared_ptr<CursorResultSet>(new CursorResultSet(conn, cursor_name, cursor_fetch_size_));

     } else {
         // no cursor
#ifdef MAPNIK_DEBUG
         std::clog << sql << "\n";
#endif
         return conn->executeQuery(sql,1);
     }
}

featureset_ptr postgis_datasource::features(const query& q) const
{
   Envelope<double> const& box=q.get_bbox();
   ConnectionManager *mgr=ConnectionManager::instance();
   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
         std::ostringstream s;

         s << "SELECT AsBinary(\""<<geometryColumn_<<"\") AS geom";
         std::set<std::string> const& props=q.property_names();
         std::set<std::string>::const_iterator pos=props.begin();
         std::set<std::string>::const_iterator end=props.end();
         while (pos != end)
         {
            s <<",\""<<*pos<<"\"";
            ++pos;
         }
         s << " from " << table_ << " WHERE \""<<geometryColumn_<<"\" && SetSRID('BOX3D(";
         s << std::setprecision(16);
         s << box.minx() << " " << box.miny() << ",";
         s << box.maxx() << " " << box.maxy() << ")'::box3d,"<<srid_<<")";

         if (row_limit_ > 0) {
             s << " LIMIT " << row_limit_;
         }

         boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
         return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),multiple_geometries_,props.size()));
      }
   }
   return featureset_ptr();
}

featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
{
   ConnectionManager *mgr=ConnectionManager::instance();
   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
         std::ostringstream s;

         s << "SELECT AsBinary(\"" << geometryColumn_ << "\") AS geom";

         std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
         std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
         unsigned size=0;
         while (itr != end)
         {
            s <<",\""<< itr->get_name() << "\"";
            ++itr;
            ++size;
         }

         s << " FROM " << table_ << " WHERE \""<<geometryColumn_<<"\" && SetSRID('BOX3D(";
         s << std::setprecision(16);
         s << pt.x << " " << pt.y << ",";
         s << pt.x << " " << pt.y << ")'::box3d,"<<srid_<<")";

         if (row_limit_ > 0) {
             s << " LIMIT " << row_limit_;
         }

         boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
         return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),multiple_geometries_, size));
      }
   }
   return featureset_ptr();
}

Envelope<double> postgis_datasource::envelope() const
{
   if (extent_initialized_) return extent_;

   ConnectionManager *mgr=ConnectionManager::instance();
   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
         std::ostringstream s;
         std::string table_name = table_from_sql(table_);
         boost::optional<std::string> estimate_extent = params_.get<std::string>("estimate_extent");

         if (estimate_extent && *estimate_extent == "true")
         {
            s << "select xmin(ext),ymin(ext),xmax(ext),ymax(ext)"
              << " from (select estimated_extent('"
              << table_name <<"','"
              << geometryColumn_ << "') as ext) as tmp";
         }
         else
         {
            s << "select xmin(ext),ymin(ext),xmax(ext),ymax(ext)"
              << " from (select extent(" <<geometryColumn_<< ") as ext from "
              << table_name << ") as tmp";
         }

         shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
         if (rs->next())
         {
            try
            {
               double lox=lexical_cast<double>(rs->getValue(0));
               double loy=lexical_cast<double>(rs->getValue(1));
               double hix=lexical_cast<double>(rs->getValue(2));
               double hiy=lexical_cast<double>(rs->getValue(3));
               extent_.init(lox,loy,hix,hiy);
               extent_initialized_ = true;
            }
            catch (bad_lexical_cast &ex)
            {
               clog << ex.what() << endl;
            }
         }
         rs->close();
      }
   }
   return extent_;
}

postgis_datasource::~postgis_datasource() {}
<commit_msg>+ applied patch from numenor <commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

//$Id: postgis.cc 44 2005-04-22 18:53:54Z pavlenko $

// mapnik
#include "connection_manager.hpp"
#include "postgis.hpp"
#include <mapnik/ptree_helpers.hpp>

// boost
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>

// stl
#include <string>
#include <algorithm>
#include <set>
#include <sstream>
#include <iomanip>

DATASOURCE_PLUGIN(postgis_datasource)

const std::string postgis_datasource::GEOMETRY_COLUMNS="geometry_columns";
const std::string postgis_datasource::SPATIAL_REF_SYS="spatial_ref_system";

using std::clog;
using std::endl;

using boost::lexical_cast;
using boost::bad_lexical_cast;
using boost::shared_ptr;

using mapnik::PoolGuard;
using mapnik::attribute_descriptor;

postgis_datasource::postgis_datasource(parameters const& params)
   : datasource (params),
     table_(*params.get<std::string>("table","")),
     geometry_field_(*params.get<std::string>("geometry_field","")),
     cursor_fetch_size_(*params_.get<int>("cursor_size",0)),
     row_limit_(*params_.get<int>("row_limit",0)),
     type_(datasource::Vector),
     extent_initialized_(false),
     desc_(*params.get<std::string>("type"),"utf-8"),
     creator_(params.get<std::string>("host"),
              params.get<std::string>("port"),
              params.get<std::string>("dbname"),
              params.get<std::string>("user"),
              params.get<std::string>("password"))
{

   boost::optional<int> initial_size = params_.get<int>("inital_size",1);
   boost::optional<int> max_size = params_.get<int>("max_size",10);

   multiple_geometries_ = *params_.get<mapnik::boolean>("multiple_geometries",false);

   boost::optional<std::string> ext  = params_.get<std::string>("extent");
   if (ext)
   {
      boost::char_separator<char> sep(",");
      boost::tokenizer<boost::char_separator<char> > tok(*ext,sep);
      unsigned i = 0;
      bool success = false;
      double d[4];
      for (boost::tokenizer<boost::char_separator<char> >::iterator beg=tok.begin();
           beg!=tok.end();++beg)
      {
         try
         {
             d[i] = boost::lexical_cast<double>(*beg);
         }
         catch (boost::bad_lexical_cast & ex)
         {
            std::clog << ex.what() << "\n";
            break;
         }
         if (i==3)
         {
            success = true;
            break;
         }
         ++i;
      }
      if (success)
      {
         extent_.init(d[0],d[1],d[2],d[3]);
         extent_initialized_ = true;
      }
   }

   ConnectionManager *mgr=ConnectionManager::instance();
   mgr->registerPool(creator_, *initial_size, *max_size);

   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,
            shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);

         desc_.set_encoding(conn->client_encoding());

         std::string table_name=table_from_sql(table_);
         std::string schema_name="";
         std::string::size_type idx=table_name.find_last_of('.');
         if (idx!=std::string::npos)
         {
            schema_name=table_name.substr(0,idx);
            table_name=table_name.substr(idx+1);
         }
         else
         {
            table_name=table_name.substr(0);
         }

         std::ostringstream s;
         s << "select f_geometry_column,srid,type from ";
         s << GEOMETRY_COLUMNS <<" where f_table_name='" << table_name<<"'";

         if (schema_name.length() > 0)
            s <<" and f_table_schema='"<< schema_name <<"'";

         if (geometry_field_.length() > 0)
            s << " and f_geometry_column = '" << geometry_field_ << "'";

         shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
         if (rs->next())
         {
            try
            {
               srid_ = lexical_cast<int>(rs->getValue("srid"));
            }
            catch (bad_lexical_cast &ex)
            {
               clog << ex.what() << endl;
            }
            geometryColumn_=rs->getValue("f_geometry_column");
            std::string postgisType=rs->getValue("type");
         }
         rs->close();

         // collect attribute desc
         s.str("");
         s << "select * from " << table_ << " limit 0";
         rs=conn->executeQuery(s.str());
         int count = rs->getNumFields();
         for (int i=0;i<count;++i)
         {
            std::string fld_name=rs->getFieldName(i);
            int type_oid = rs->getTypeOID(i);
            switch (type_oid)
            {
               case 21:    // int2
               case 23:    // int4
                  desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
                  break;
               case 700:   // float4
               case 701:   // float8
               case 1700:  // numeric ??
                  desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Double));
               case 1042:  // bpchar
               case 1043:  // varchar
               case 25:    // text
                  desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::String));
                  break;
               default: // shouldn't get here
#ifdef MAPNIK_DEBUG
                  clog << "unknown type_oid="<<type_oid<<endl;
#endif
                  break;
            }
         }
      }
   }
}

std::string const postgis_datasource::name_="postgis";

std::string postgis_datasource::name()
{
   return name_;
}

int postgis_datasource::type() const
{
   return type_;
}

layer_descriptor postgis_datasource::get_descriptor() const
{
   return desc_;
}

std::string postgis_datasource::table_from_sql(const std::string& sql)
{
   std::string table_name = boost::algorithm::to_lower_copy(sql);
   boost::algorithm::replace_all(table_name,"\n"," ");

   std::string::size_type idx = table_name.rfind(" from ");
   if (idx!=std::string::npos)
   {

      idx=table_name.find_first_not_of(" ",idx+5);
      if (idx != std::string::npos)
      {
         table_name=table_name.substr(idx);
      }
      idx=table_name.find_first_of(" )");
      if (idx != std::string::npos)
      {
         table_name = table_name.substr(0,idx);
      }
   }
   return table_name;
}

boost::shared_ptr<IResultSet> postgis_datasource::get_resultset(boost::shared_ptr<Connection> const &conn, const std::string &sql) const
{
     if (cursor_fetch_size_ > 0) {
         // cursor
         std::ostringstream csql;
         std::string cursor_name = conn->new_cursor_name();

         csql << "DECLARE " << cursor_name << " BINARY INSENSITIVE NO SCROLL CURSOR WITH HOLD FOR " << sql << " FOR READ ONLY";

#ifdef MAPNIK_DEBUG
         std::clog << csql.str() << "\n";
#endif
         if (!conn->execute(csql.str())) {
            throw mapnik::datasource_exception( "PSQL Error: Creating cursor for data select." );
         }
         return shared_ptr<CursorResultSet>(new CursorResultSet(conn, cursor_name, cursor_fetch_size_));

     } else {
         // no cursor
#ifdef MAPNIK_DEBUG
         std::clog << sql << "\n";
#endif
         return conn->executeQuery(sql,1);
     }
}

featureset_ptr postgis_datasource::features(const query& q) const
{
   Envelope<double> const& box=q.get_bbox();
   ConnectionManager *mgr=ConnectionManager::instance();
   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
         std::ostringstream s;

         s << "SELECT AsBinary(\""<<geometryColumn_<<"\") AS geom";
         std::set<std::string> const& props=q.property_names();
         std::set<std::string>::const_iterator pos=props.begin();
         std::set<std::string>::const_iterator end=props.end();
         while (pos != end)
         {
            s <<",\""<<*pos<<"\"";
            ++pos;
         }
         s << " from " << table_ << " WHERE \""<<geometryColumn_<<"\" && SetSRID('BOX3D(";
         s << std::setprecision(16);
         s << box.minx() << " " << box.miny() << ",";
         s << box.maxx() << " " << box.maxy() << ")'::box3d,"<<srid_<<")";

         if (row_limit_ > 0) {
             s << " LIMIT " << row_limit_;
         }

         boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
         return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),multiple_geometries_,props.size()));
      }
   }
   return featureset_ptr();
}

featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const
{
   ConnectionManager *mgr=ConnectionManager::instance();
   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
         std::ostringstream s;

         s << "SELECT AsBinary(\"" << geometryColumn_ << "\") AS geom";

         std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin();
         std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end();
         unsigned size=0;
         while (itr != end)
         {
            s <<",\""<< itr->get_name() << "\"";
            ++itr;
            ++size;
         }

         s << " FROM " << table_ << " WHERE \""<<geometryColumn_<<"\" && SetSRID('BOX3D(";
         s << std::setprecision(16);
         s << pt.x << " " << pt.y << ",";
         s << pt.x << " " << pt.y << ")'::box3d,"<<srid_<<")";

         if (row_limit_ > 0) {
             s << " LIMIT " << row_limit_;
         }

         boost::shared_ptr<IResultSet> rs = get_resultset(conn, s.str());
         return featureset_ptr(new postgis_featureset(rs,desc_.get_encoding(),multiple_geometries_, size));
      }
   }
   return featureset_ptr();
}

Envelope<double> postgis_datasource::envelope() const
{
   if (extent_initialized_) return extent_;

   ConnectionManager *mgr=ConnectionManager::instance();
   shared_ptr<Pool<Connection,ConnectionCreator> > pool=mgr->getPool(creator_.id());
   if (pool)
   {
      shared_ptr<Connection> conn = pool->borrowObject();
      if (conn && conn->isOK())
      {
         PoolGuard<shared_ptr<Connection>,shared_ptr<Pool<Connection,ConnectionCreator> > > guard(conn,pool);
         std::ostringstream s;
         std::string table_name = table_from_sql(table_);
         boost::optional<std::string> estimate_extent = params_.get<std::string>("estimate_extent");

         if (estimate_extent && *estimate_extent == "true")
         {
            s << "select xmin(ext),ymin(ext),xmax(ext),ymax(ext)"
              << " from (select estimated_extent('"
              << table_name <<"','"
              << geometryColumn_ << "') as ext) as tmp";
         }
         else
         {
            s << "select xmin(ext),ymin(ext),xmax(ext),ymax(ext)"
              << " from (select extent(" <<geometryColumn_<< ") as ext from "
              << table_name << ") as tmp";
         }

         shared_ptr<ResultSet> rs=conn->executeQuery(s.str());
         if (rs->next())
         {
            try
            {
               double lox=lexical_cast<double>(rs->getValue(0));
               double loy=lexical_cast<double>(rs->getValue(1));
               double hix=lexical_cast<double>(rs->getValue(2));
               double hiy=lexical_cast<double>(rs->getValue(3));
               extent_.init(lox,loy,hix,hiy);
               extent_initialized_ = true;
            }
            catch (bad_lexical_cast &ex)
            {
               clog << ex.what() << endl;
            }
         }
         rs->close();
      }
   }
   return extent_;
}

postgis_datasource::~postgis_datasource() {}
<|endoftext|>


<commit_before>#include "util/json.hh"

#include <fstream>
#include <stdexcept>

using namespace std;

namespace g4
{
    namespace util
    {
        shared_ptr<Json::Value> parseJsonFile(const std::string& path)
        {
            ifstream file(path);
            if (!file)
            {
                throw runtime_error("File does not exist.");
            }
            string content(
                (std::istreambuf_iterator<char>(file) ),
                (std::istreambuf_iterator<char>()    )
            );

            shared_ptr<Json::Value> root(new Json::Value);
            Json::Reader reader;

            reader.parse(content, *root);
            return root;
        }
    }
}<commit_msg>More explicit exception in JSON reading<commit_after>#include "util/json.hh"

#include <fstream>
#include <stdexcept>

using namespace std;

namespace g4
{
    namespace util
    {
        shared_ptr<Json::Value> parseJsonFile(const std::string& path)
        {
            ifstream file(path);
            if (!file)
            {
                // TODO: G4Exception?
                throw runtime_error(string("File does not exist: ") + path);
            }
            string content(
                (std::istreambuf_iterator<char>(file) ),
                (std::istreambuf_iterator<char>()    )
            );

            shared_ptr<Json::Value> root(new Json::Value);
            Json::Reader reader;

            reader.parse(content, *root);
            return root;
        }
    }
}<|endoftext|>


<commit_before>/*
* Copyright (c) 2006, Ondrej Danek (www.ondrej-danek.net)
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Ondrej Danek nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
Projekt: Konzole
Popis: Zpracovani prikazove radky
*/

#include "console.h"

/*
==================================================
Opravi pozici od ktere se zobrazuje prikazova radka
==================================================
*/
void con_c::setinputscroll (void)
{
    int     l = (int)m_input.length(), width = m_width - 1;

    if (m_curpos == l)
    {
        m_inputscroll = (l + 2) - m_width;
        if (m_inputscroll < 0)
            m_inputscroll = 0;
        return;
    }

    if (l <= width)
    {
        m_inputscroll = 0;
        return;
    }

    if (l - m_inputscroll < width)
        m_inputscroll = l - width;

    if (m_curpos < m_inputscroll)
        m_inputscroll = m_curpos;

    if (m_curpos >= m_inputscroll + width)
        m_inputscroll = 1 + m_curpos - width;
}

/*
==================================================
Dohledani prikazu
==================================================
*/
static bool startsWith(const std::string& text, const std::string& prefix)
{
	return prefix.length() <= text.length() && text.compare(0, prefix.length(), prefix) == 0;
}

void con_c::completecmd (void)
{
	if (m_input.empty())
	{
		return;
	}

	std::vector<std::string> fittingCommands;
	for (const conCommand_s& command : m_procs)
	{
		if (startsWith(command.name, m_input))
		{
			fittingCommands.push_back(command.name);
		}
	}
	for (const conVar_s& var : m_vars)
	{
		if (startsWith(var.name, m_input))
		{
			fittingCommands.push_back(var.name);
		}
	}
	for (const conAlias_s& alias : m_alias)
	{
		if (startsWith(alias.name, m_input))
		{
			fittingCommands.push_back(alias.name);
		}
	}

	if (fittingCommands.size() == 1)
	{
		m_input = fittingCommands.front();
		m_input.append(" ");
		m_curpos = m_input.length();
	}
	else if (fittingCommands.size() > 1)
	{
        printf(CON_Lang("CONSTR0028|]Hledani: \"%s\"\n"), m_input.c_str());
		for (const std::string& command : fittingCommands)
		{
			printf("\t%s\n", command.c_str());
		}

		std::string largestFit = fittingCommands.front();
		for (const std::string& command : fittingCommands)
		{
			size_t prefix = m_input.length();
			while (prefix < largestFit.length() && prefix < command.length() && largestFit[prefix] == command[prefix])
			{
				++prefix;
			}

			if (prefix < largestFit.length())
			{
				largestFit = largestFit.substr(0, prefix);
			}
		}

		m_input = largestFit;
		m_curpos = m_input.length();
	}
}

/*
==================================================
Reakce na stisk klavesy
==================================================
*/
void con_c::keyEvent(SDL_Keycode keyCode)
{
    int len = (int)m_input.length();

    switch (keyCode)
    {
    case CON_C_SCROLL_UP:
        m_scroll++;
        break;
    case CON_C_SCROLL_DOWN:
        if (m_scroll > 0)
            m_scroll--;
        break;
    case CON_C_HIST_UP:
        if (m_histscroll < CON_REM_HIST && m_histcnt - m_histscroll > 0)
        {
            m_histscroll++;
			m_input = m_hist[(m_histcnt - m_histscroll) % CON_REM_HIST];
            m_curpos = (int)m_input.length();
        }
        break;
    case CON_C_HIST_DOWN:
        if (m_histscroll > 0)
        {
            m_histscroll--;
			if (!m_histscroll)
			{
				m_input.clear();
			}
			else
			{
				m_input = m_hist[(m_histcnt - m_histscroll) % CON_REM_HIST];
			}
            m_curpos = (int) m_input.length();
        }
        break;
    case CON_C_INSERT:
        m_insert = !m_insert;
        break;
	case CON_C_BACK:
		if (m_curpos > 0)
        {
			m_input.erase(m_input.begin() + m_curpos - 1);
            m_curpos--;
        }
		break;
	case CON_C_DELETE:
		if (m_curpos < len)
        {
			m_input.erase(m_input.begin() + m_curpos);
        }
		break;
	case CON_C_ENTER:
		if (len)
        {
            m_hist[m_histcnt % CON_REM_HIST] = m_input;
            m_histcnt++;
            m_histscroll = 0;
            printf ("]%s\n", m_input.c_str());
            exec(m_input);
            m_input.clear();
            m_curpos = 0;
        }
		break;
	case CON_C_TAB:
        completecmd();
		break;
	case CON_C_LEFT:
		if (m_curpos > 0)
		{
			m_curpos--;
		}
		break;
	case CON_C_RIGHT:
		if (m_curpos < len)
		{
			m_curpos++;
		}
		break;
	case CON_C_HOME:
        m_curpos = 0;
		break;
	case CON_C_END:
        m_curpos = len;
        break;
    }

    setinputscroll ();
}

void con_c::textInputEvent(const char* text)
{
	while (*text != 0)
	{
		if (*text >= ' ' && *text < 128 && *text != '`')
		{
			if (!m_insert || m_curpos == m_input.length())
			{
				m_input.insert(m_input.begin() + m_curpos, *text);
				++m_curpos;
			}
			else
			{
				m_input[m_curpos++] = *text;
			}
		}

		text++;
	}
}
<commit_msg>Fix GCC warning (signed/unsigned mismatch).<commit_after>/*
* Copyright (c) 2006, Ondrej Danek (www.ondrej-danek.net)
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Ondrej Danek nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
Projekt: Konzole
Popis: Zpracovani prikazove radky
*/

#include "console.h"

/*
==================================================
Opravi pozici od ktere se zobrazuje prikazova radka
==================================================
*/
void con_c::setinputscroll (void)
{
    int     l = (int)m_input.length(), width = m_width - 1;

    if (m_curpos == l)
    {
        m_inputscroll = (l + 2) - m_width;
        if (m_inputscroll < 0)
            m_inputscroll = 0;
        return;
    }

    if (l <= width)
    {
        m_inputscroll = 0;
        return;
    }

    if (l - m_inputscroll < width)
        m_inputscroll = l - width;

    if (m_curpos < m_inputscroll)
        m_inputscroll = m_curpos;

    if (m_curpos >= m_inputscroll + width)
        m_inputscroll = 1 + m_curpos - width;
}

/*
==================================================
Dohledani prikazu
==================================================
*/
static bool startsWith(const std::string& text, const std::string& prefix)
{
	return prefix.length() <= text.length() && text.compare(0, prefix.length(), prefix) == 0;
}

void con_c::completecmd (void)
{
	if (m_input.empty())
	{
		return;
	}

	std::vector<std::string> fittingCommands;
	for (const conCommand_s& command : m_procs)
	{
		if (startsWith(command.name, m_input))
		{
			fittingCommands.push_back(command.name);
		}
	}
	for (const conVar_s& var : m_vars)
	{
		if (startsWith(var.name, m_input))
		{
			fittingCommands.push_back(var.name);
		}
	}
	for (const conAlias_s& alias : m_alias)
	{
		if (startsWith(alias.name, m_input))
		{
			fittingCommands.push_back(alias.name);
		}
	}

	if (fittingCommands.size() == 1)
	{
		m_input = fittingCommands.front();
		m_input.append(" ");
		m_curpos = m_input.length();
	}
	else if (fittingCommands.size() > 1)
	{
        printf(CON_Lang("CONSTR0028|]Hledani: \"%s\"\n"), m_input.c_str());
		for (const std::string& command : fittingCommands)
		{
			printf("\t%s\n", command.c_str());
		}

		std::string largestFit = fittingCommands.front();
		for (const std::string& command : fittingCommands)
		{
			size_t prefix = m_input.length();
			while (prefix < largestFit.length() && prefix < command.length() && largestFit[prefix] == command[prefix])
			{
				++prefix;
			}

			if (prefix < largestFit.length())
			{
				largestFit = largestFit.substr(0, prefix);
			}
		}

		m_input = largestFit;
		m_curpos = m_input.length();
	}
}

/*
==================================================
Reakce na stisk klavesy
==================================================
*/
void con_c::keyEvent(SDL_Keycode keyCode)
{
    int len = (int)m_input.length();

    switch (keyCode)
    {
    case CON_C_SCROLL_UP:
        m_scroll++;
        break;
    case CON_C_SCROLL_DOWN:
        if (m_scroll > 0)
            m_scroll--;
        break;
    case CON_C_HIST_UP:
        if (m_histscroll < CON_REM_HIST && m_histcnt - m_histscroll > 0)
        {
            m_histscroll++;
			m_input = m_hist[(m_histcnt - m_histscroll) % CON_REM_HIST];
            m_curpos = (int)m_input.length();
        }
        break;
    case CON_C_HIST_DOWN:
        if (m_histscroll > 0)
        {
            m_histscroll--;
			if (!m_histscroll)
			{
				m_input.clear();
			}
			else
			{
				m_input = m_hist[(m_histcnt - m_histscroll) % CON_REM_HIST];
			}
            m_curpos = (int) m_input.length();
        }
        break;
    case CON_C_INSERT:
        m_insert = !m_insert;
        break;
	case CON_C_BACK:
		if (m_curpos > 0)
        {
			m_input.erase(m_input.begin() + m_curpos - 1);
            m_curpos--;
        }
		break;
	case CON_C_DELETE:
		if (m_curpos < len)
        {
			m_input.erase(m_input.begin() + m_curpos);
        }
		break;
	case CON_C_ENTER:
		if (len)
        {
            m_hist[m_histcnt % CON_REM_HIST] = m_input;
            m_histcnt++;
            m_histscroll = 0;
            printf ("]%s\n", m_input.c_str());
            exec(m_input);
            m_input.clear();
            m_curpos = 0;
        }
		break;
	case CON_C_TAB:
        completecmd();
		break;
	case CON_C_LEFT:
		if (m_curpos > 0)
		{
			m_curpos--;
		}
		break;
	case CON_C_RIGHT:
		if (m_curpos < len)
		{
			m_curpos++;
		}
		break;
	case CON_C_HOME:
        m_curpos = 0;
		break;
	case CON_C_END:
        m_curpos = len;
        break;
    }

    setinputscroll ();
}

void con_c::textInputEvent(const char* text)
{
	while (*text != 0)
	{
		if (*text >= ' ' && *text < 128 && *text != '`')
		{
			if (!m_insert || m_curpos == (int)m_input.length())
			{
				m_input.insert(m_input.begin() + m_curpos, *text);
				++m_curpos;
			}
			else
			{
				m_input[m_curpos++] = *text;
			}
		}

		text++;
	}
}
<|endoftext|>