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

#if qPlatform_Windows
#include <Windows.h>

#include <shellapi.h>
#include <winerror.h>
#include <wininet.h> // for error codes
#else
#error "WINDOWS REQUIRED FOR THIS MODULE"
#endif

#include "../../../Characters/CString/Utilities.h"
#include "../../../Characters/Format.h"
#include "../../../Configuration/Common.h"
#include "../../../Containers/Common.h"
#include "../../../Debug/Trace.h"
#include "../../../Execution/TimeOutException.h"
#if qPlatform_Windows
#include "HRESULTErrorException.h"
#endif
#include "../../../IO/FileAccessException.h"
#include "../../../IO/FileBusyException.h"
#include "../../../Time/Realtime.h"

#include "Exception.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Debug;
using namespace Stroika::Foundation::Execution;
using namespace Stroika::Foundation::Execution::Platform;
using namespace Stroika::Foundation::Execution::Platform::Windows;

// for InternetGetConnectedState
#if _MSC_VER
#pragma comment(lib, "Wininet.lib")
#endif

namespace {
    inline SDKString Win32Error2String_ (DWORD win32Err)
    {
        switch (win32Err) {
            case ERROR_NOT_ENOUGH_MEMORY:
                return SDKSTR ("Not enough memory to complete that operation (ERROR_NOT_ENOUGH_MEMORY)");
            case ERROR_OUTOFMEMORY:
                return SDKSTR ("Not enough memory to complete that operation (ERROR_OUTOFMEMORY)");
        }
        if (INTERNET_ERROR_BASE <= win32Err and win32Err < INTERNET_ERROR_BASE + INTERNET_ERROR_LAST) {
            switch (win32Err) {
                case ERROR_INTERNET_INVALID_URL:
                    return SDKSTR ("ERROR_INTERNET_INVALID_URL");
                case ERROR_INTERNET_CANNOT_CONNECT:
                    return SDKSTR ("Failed to connect to internet URL (ERROR_INTERNET_CANNOT_CONNECT)");
                case ERROR_INTERNET_NAME_NOT_RESOLVED:
                    return SDKSTR ("ERROR_INTERNET_NAME_NOT_RESOLVED");
                case ERROR_INTERNET_INCORRECT_HANDLE_STATE:
                    return SDKSTR ("ERROR_INTERNET_INCORRECT_HANDLE_STATE");
                case ERROR_INTERNET_TIMEOUT:
                    return SDKSTR ("Operation timed out (ERROR_INTERNET_TIMEOUT)");
                case ERROR_INTERNET_CONNECTION_ABORTED:
                    return SDKSTR ("ERROR_INTERNET_CONNECTION_ABORTED");
                case ERROR_INTERNET_CONNECTION_RESET:
                    return SDKSTR ("ERROR_INTERNET_CONNECTION_RESET");
                case ERROR_HTTP_INVALID_SERVER_RESPONSE:
                    return SDKSTR ("Invalid Server Response (ERROR_HTTP_INVALID_SERVER_RESPONSE)");
                case ERROR_INTERNET_PROTOCOL_NOT_FOUND: {
                    DWORD r = 0;
                    if (::InternetGetConnectedState (&r, 0) and (r & INTERNET_CONNECTION_OFFLINE) == 0) {
                        return SDKSTR ("ERROR_INTERNET_PROTOCOL_NOT_FOUND");
                    }
                    else {
                        return SDKSTR ("ERROR_INTERNET_PROTOCOL_NOT_FOUND (offline mode)");
                    }
                }
                default: {
                    TCHAR buf[1024];
                    (void)::_stprintf_s (buf, SDKSTR ("INTERNET error code: %d"), win32Err);
                    return buf;
                }
            }
        }
        TCHAR* lpMsgBuf = nullptr;
        if (not::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                nullptr,
                                win32Err,
                                MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                                reinterpret_cast<TCHAR*> (&lpMsgBuf),
                                0,
                                nullptr)) {
            return CString::Format (SDKSTR ("Win32 error# %d"), static_cast<DWORD> (win32Err));
        }
        SDKString result = lpMsgBuf;
        ::LocalFree (lpMsgBuf);
        return CString::Trim (result);
    }
}

/*
 ********************************************************************************
 *********************** Platform::Windows::Exception ***************************
 ********************************************************************************
 */
Exception::Exception (DWORD error)
    : StringException (SDKString2Wide (Win32Error2String_ (error)))
    , fError (error)
{
}

void Execution::Platform::Windows::Exception::Throw (DWORD error)
{
    switch (error) {
        case ERROR_SUCCESS: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpointBacktrace
            DbgTrace ("Platform::Windows::Exception::Throw (ERROR_SUCCESS) - throwing Platform::Windows::Exception (ERROR_NOT_SUPPORTED) from %s", Execution::Private_::GetBT_s ().c_str ());
#else
            DbgTrace ("Platform::Windows::Exception::Throw (ERROR_SUCCESS) - throwing Platform::Windows::Exception (ERROR_NOT_SUPPORTED)");
#endif
#endif
            // unsure WHAT to throw here - SOMETHING failed - but GetLastError () must have given
            // a bad reason code?
            throw Platform::Windows::Exception (ERROR_NOT_SUPPORTED);
        }
        case ERROR_NOT_ENOUGH_MEMORY:
        case ERROR_OUTOFMEMORY: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing bad_alloc", error);
#endif
            Execution::Throw (bad_alloc ());
        }
        case ERROR_SHARING_VIOLATION: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileBusyException", error);
#endif
            Execution::Throw (IO::FileBusyException ());
        }
        case ERROR_ACCESS_DENIED: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileAccessException", error);
#endif
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case ERROR_FILE_NOT_FOUND: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileAccessException", error);
#endif
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case ERROR_PATH_NOT_FOUND: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileAccessException", error);
#endif
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case WAIT_TIMEOUT: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing TimeOutException", error);
#endif
            Execution::Throw (Execution::TimeOutException ());
        }
        default: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpointBacktrace
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing Platform::Windows::Exception from %s", error, Execution::Private_::GetBT_s ().c_str ());
#else
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing Platform::Windows::Exception", error);
#endif
#endif
            throw Platform::Windows::Exception (error);
        }
    }
}

SDKString Execution::Platform::Windows::Exception::LookupMessage (DWORD dw)
{
    return Win32Error2String_ (dw);
}

/*
 ********************************************************************************
 ***************************** ThrowIfShellExecError ****************************
 ********************************************************************************
 */
void Execution::Platform::Windows::ThrowIfShellExecError (HINSTANCE r)
{
    DISABLE_COMPILER_MSC_WARNING_START (4302)
    DISABLE_COMPILER_MSC_WARNING_START (4311)
    int errCode = reinterpret_cast<int> (r);
    DISABLE_COMPILER_MSC_WARNING_END (4311)
    DISABLE_COMPILER_MSC_WARNING_END (4302)
    if (errCode <= 32) {
        DbgTrace ("ThrowIfShellExecError (0x%x) - throwing exception", errCode);
        switch (errCode) {
            case 0:
                Platform::Windows::Exception::Throw (ERROR_NOT_ENOUGH_MEMORY); // The operating system is out of memory or resources.
            case ERROR_FILE_NOT_FOUND:
                Platform::Windows::Exception::Throw (ERROR_FILE_NOT_FOUND); // The specified file was not found.
            case ERROR_PATH_NOT_FOUND:
                Platform::Windows::Exception::Throw (ERROR_PATH_NOT_FOUND); //  The specified path was not found.
            case ERROR_BAD_FORMAT:
                Platform::Windows::Exception::Throw (ERROR_BAD_FORMAT); //  The .exe file is invalid (non-Microsoft Win32 .exe or error in .exe image).
            case SE_ERR_ACCESSDENIED:
                throw (Platform::Windows::HRESULTErrorException (E_ACCESSDENIED)); //  The operating system denied access to the specified file.
            case SE_ERR_ASSOCINCOMPLETE:
                Platform::Windows::Exception::Throw (ERROR_NO_ASSOCIATION); //  The file name association is incomplete or invalid.
            case SE_ERR_DDEBUSY:
                Platform::Windows::Exception::Throw (ERROR_DDE_FAIL); //  The Dynamic Data Exchange (DDE) transaction could not be completed because other DDE transactions were being processed.
            case SE_ERR_DDEFAIL:
                Platform::Windows::Exception::Throw (ERROR_DDE_FAIL); //  The DDE transaction failed.
            case SE_ERR_DDETIMEOUT:
                Platform::Windows::Exception::Throw (ERROR_DDE_FAIL); //  The DDE transaction could not be completed because the request timed out.
            case SE_ERR_DLLNOTFOUND:
                Platform::Windows::Exception::Throw (ERROR_DLL_NOT_FOUND); //  The specified dynamic-link library (DLL) was not found.
            //case  SE_ERR_FNF:             throw (Platform::Windows::Exception (ERROR_FILE_NOT_FOUND));        //  The specified file was not found.
            case SE_ERR_NOASSOC:
                Platform::Windows::Exception::Throw (ERROR_NO_ASSOCIATION); //  There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable.
            case SE_ERR_OOM:
                Platform::Windows::Exception::Throw (ERROR_NOT_ENOUGH_MEMORY); //  There was not enough memory to complete the operation.
            //case  SE_ERR_PNF:             throw (Platform::Windows::Exception (ERROR_PATH_NOT_FOUND));        //  The specified path was not found.
            case SE_ERR_SHARE:
                Platform::Windows::Exception::Throw (ERROR_INVALID_SHARENAME); //
            default: {
                // Not sure what error to report here...
                Platform::Windows::Exception::Throw (ERROR_NO_ASSOCIATION);
            }
        }
    }
}

/*
 ********************************************************************************
 *********** Execution::RegisterDefaultHandler_invalid_parameter ****************
 ********************************************************************************
 */
namespace {
    /*
     *  Because of Microsoft's new secure-runtime-lib  - we must provide a handler to catch errors (shouldn't occur - but in case.
     *  We treat these largely like ASSERTION errors, but then translate them into a THROW of an exception - since that is
     *  probably more often the right thing todo.
     */
    void invalid_parameter_handler_ (const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
    {
        TraceContextBumper trcCtx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"invalid_parameter_handler", L"Func='%s', expr='%s', file='%s'.", function, expression, file)};
        Assert (false);
        Execution::Throw (Execution::Platform::Windows::Exception (ERROR_INVALID_PARAMETER));
    }
}
void Execution::Platform::Windows::RegisterDefaultHandler_invalid_parameter ()
{
    (void)_set_invalid_parameter_handler (invalid_parameter_handler_);
}
<commit_msg>Also treat ERROR_WINHTTP_TIMEOUT as generating a Timeout excpetion<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2018.  All rights reserved
 */
#include "../../../StroikaPreComp.h"

#if qPlatform_Windows
#include <Windows.h>

#include <shellapi.h>
#include <winerror.h>
#include <winhttp.h> // for error codes
#include <wininet.h> // for error codes
#else
#error "WINDOWS REQUIRED FOR THIS MODULE"
#endif

#include "../../../Characters/CString/Utilities.h"
#include "../../../Characters/Format.h"
#include "../../../Configuration/Common.h"
#include "../../../Containers/Common.h"
#include "../../../Debug/Trace.h"
#include "../../../Execution/TimeOutException.h"
#if qPlatform_Windows
#include "HRESULTErrorException.h"
#endif
#include "../../../IO/FileAccessException.h"
#include "../../../IO/FileBusyException.h"
#include "../../../Time/Realtime.h"

#include "Exception.h"

using namespace Stroika;
using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Debug;
using namespace Stroika::Foundation::Execution;
using namespace Stroika::Foundation::Execution::Platform;
using namespace Stroika::Foundation::Execution::Platform::Windows;

// for InternetGetConnectedState
#if _MSC_VER
#pragma comment(lib, "Wininet.lib")
#endif

namespace {
    inline SDKString Win32Error2String_ (DWORD win32Err)
    {
        switch (win32Err) {
            case ERROR_NOT_ENOUGH_MEMORY:
                return SDKSTR ("Not enough memory to complete that operation (ERROR_NOT_ENOUGH_MEMORY)");
            case ERROR_OUTOFMEMORY:
                return SDKSTR ("Not enough memory to complete that operation (ERROR_OUTOFMEMORY)");
        }
        if (INTERNET_ERROR_BASE <= win32Err and win32Err < INTERNET_ERROR_BASE + INTERNET_ERROR_LAST) {
            switch (win32Err) {
                case ERROR_INTERNET_INVALID_URL:
                    return SDKSTR ("ERROR_INTERNET_INVALID_URL");
                case ERROR_INTERNET_CANNOT_CONNECT:
                    return SDKSTR ("Failed to connect to internet URL (ERROR_INTERNET_CANNOT_CONNECT)");
                case ERROR_INTERNET_NAME_NOT_RESOLVED:
                    return SDKSTR ("ERROR_INTERNET_NAME_NOT_RESOLVED");
                case ERROR_INTERNET_INCORRECT_HANDLE_STATE:
                    return SDKSTR ("ERROR_INTERNET_INCORRECT_HANDLE_STATE");
                case ERROR_INTERNET_TIMEOUT:
                    return SDKSTR ("Operation timed out (ERROR_INTERNET_TIMEOUT)");
                case ERROR_INTERNET_CONNECTION_ABORTED:
                    return SDKSTR ("ERROR_INTERNET_CONNECTION_ABORTED");
                case ERROR_INTERNET_CONNECTION_RESET:
                    return SDKSTR ("ERROR_INTERNET_CONNECTION_RESET");
                case ERROR_HTTP_INVALID_SERVER_RESPONSE:
                    return SDKSTR ("Invalid Server Response (ERROR_HTTP_INVALID_SERVER_RESPONSE)");
                case ERROR_INTERNET_PROTOCOL_NOT_FOUND: {
                    DWORD r = 0;
                    if (::InternetGetConnectedState (&r, 0) and (r & INTERNET_CONNECTION_OFFLINE) == 0) {
                        return SDKSTR ("ERROR_INTERNET_PROTOCOL_NOT_FOUND");
                    }
                    else {
                        return SDKSTR ("ERROR_INTERNET_PROTOCOL_NOT_FOUND (offline mode)");
                    }
                }
                default: {
                    TCHAR buf[1024];
                    (void)::_stprintf_s (buf, SDKSTR ("INTERNET error code: %d"), win32Err);
                    return buf;
                }
            }
        }
        TCHAR* lpMsgBuf = nullptr;
        if (not::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                nullptr,
                                win32Err,
                                MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                                reinterpret_cast<TCHAR*> (&lpMsgBuf),
                                0,
                                nullptr)) {
            return CString::Format (SDKSTR ("Win32 error# %d"), static_cast<DWORD> (win32Err));
        }
        SDKString result = lpMsgBuf;
        ::LocalFree (lpMsgBuf);
        return CString::Trim (result);
    }
}

/*
 ********************************************************************************
 *********************** Platform::Windows::Exception ***************************
 ********************************************************************************
 */
Exception::Exception (DWORD error)
    : StringException (SDKString2Wide (Win32Error2String_ (error)))
    , fError (error)
{
}

void Execution::Platform::Windows::Exception::Throw (DWORD error)
{
    switch (error) {
        case ERROR_SUCCESS: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpointBacktrace
            DbgTrace ("Platform::Windows::Exception::Throw (ERROR_SUCCESS) - throwing Platform::Windows::Exception (ERROR_NOT_SUPPORTED) from %s", Execution::Private_::GetBT_s ().c_str ());
#else
            DbgTrace ("Platform::Windows::Exception::Throw (ERROR_SUCCESS) - throwing Platform::Windows::Exception (ERROR_NOT_SUPPORTED)");
#endif
#endif
            // unsure WHAT to throw here - SOMETHING failed - but GetLastError () must have given
            // a bad reason code?
            throw Platform::Windows::Exception (ERROR_NOT_SUPPORTED);
        }
        case ERROR_NOT_ENOUGH_MEMORY:
        case ERROR_OUTOFMEMORY: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing bad_alloc", error);
#endif
            Execution::Throw (bad_alloc ());
        }
        case ERROR_SHARING_VIOLATION: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileBusyException", error);
#endif
            Execution::Throw (IO::FileBusyException ());
        }
        case ERROR_ACCESS_DENIED: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileAccessException", error);
#endif
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case ERROR_FILE_NOT_FOUND: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileAccessException", error);
#endif
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case ERROR_PATH_NOT_FOUND: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing FileAccessException", error);
#endif
            Execution::Throw (IO::FileAccessException ()); // don't know if they were reading or writing at this level..., and don't know file name...
        }
        case WAIT_TIMEOUT:
        case ERROR_WINHTTP_TIMEOUT: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing TimeOutException", error);
#endif
            Execution::Throw (Execution::TimeOutException ());
        }
        default: {
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpoint
#if qStroika_Foundation_Exection_Exceptions_TraceThrowpointBacktrace
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing Platform::Windows::Exception from %s", error, Execution::Private_::GetBT_s ().c_str ());
#else
            DbgTrace ("Platform::Windows::Exception::Throw (0x%x) - throwing Platform::Windows::Exception", error);
#endif
#endif
            throw Platform::Windows::Exception (error);
        }
    }
}

SDKString Execution::Platform::Windows::Exception::LookupMessage (DWORD dw)
{
    return Win32Error2String_ (dw);
}

/*
 ********************************************************************************
 ***************************** ThrowIfShellExecError ****************************
 ********************************************************************************
 */
void Execution::Platform::Windows::ThrowIfShellExecError (HINSTANCE r)
{
    DISABLE_COMPILER_MSC_WARNING_START (4302)
    DISABLE_COMPILER_MSC_WARNING_START (4311)
    int errCode = reinterpret_cast<int> (r);
    DISABLE_COMPILER_MSC_WARNING_END (4311)
    DISABLE_COMPILER_MSC_WARNING_END (4302)
    if (errCode <= 32) {
        DbgTrace ("ThrowIfShellExecError (0x%x) - throwing exception", errCode);
        switch (errCode) {
            case 0:
                Platform::Windows::Exception::Throw (ERROR_NOT_ENOUGH_MEMORY); // The operating system is out of memory or resources.
            case ERROR_FILE_NOT_FOUND:
                Platform::Windows::Exception::Throw (ERROR_FILE_NOT_FOUND); // The specified file was not found.
            case ERROR_PATH_NOT_FOUND:
                Platform::Windows::Exception::Throw (ERROR_PATH_NOT_FOUND); //  The specified path was not found.
            case ERROR_BAD_FORMAT:
                Platform::Windows::Exception::Throw (ERROR_BAD_FORMAT); //  The .exe file is invalid (non-Microsoft Win32 .exe or error in .exe image).
            case SE_ERR_ACCESSDENIED:
                throw (Platform::Windows::HRESULTErrorException (E_ACCESSDENIED)); //  The operating system denied access to the specified file.
            case SE_ERR_ASSOCINCOMPLETE:
                Platform::Windows::Exception::Throw (ERROR_NO_ASSOCIATION); //  The file name association is incomplete or invalid.
            case SE_ERR_DDEBUSY:
                Platform::Windows::Exception::Throw (ERROR_DDE_FAIL); //  The Dynamic Data Exchange (DDE) transaction could not be completed because other DDE transactions were being processed.
            case SE_ERR_DDEFAIL:
                Platform::Windows::Exception::Throw (ERROR_DDE_FAIL); //  The DDE transaction failed.
            case SE_ERR_DDETIMEOUT:
                Platform::Windows::Exception::Throw (ERROR_DDE_FAIL); //  The DDE transaction could not be completed because the request timed out.
            case SE_ERR_DLLNOTFOUND:
                Platform::Windows::Exception::Throw (ERROR_DLL_NOT_FOUND); //  The specified dynamic-link library (DLL) was not found.
            //case  SE_ERR_FNF:             throw (Platform::Windows::Exception (ERROR_FILE_NOT_FOUND));        //  The specified file was not found.
            case SE_ERR_NOASSOC:
                Platform::Windows::Exception::Throw (ERROR_NO_ASSOCIATION); //  There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable.
            case SE_ERR_OOM:
                Platform::Windows::Exception::Throw (ERROR_NOT_ENOUGH_MEMORY); //  There was not enough memory to complete the operation.
            //case  SE_ERR_PNF:             throw (Platform::Windows::Exception (ERROR_PATH_NOT_FOUND));        //  The specified path was not found.
            case SE_ERR_SHARE:
                Platform::Windows::Exception::Throw (ERROR_INVALID_SHARENAME); //
            default: {
                // Not sure what error to report here...
                Platform::Windows::Exception::Throw (ERROR_NO_ASSOCIATION);
            }
        }
    }
}

/*
 ********************************************************************************
 *********** Execution::RegisterDefaultHandler_invalid_parameter ****************
 ********************************************************************************
 */
namespace {
    /*
     *  Because of Microsoft's new secure-runtime-lib  - we must provide a handler to catch errors (shouldn't occur - but in case.
     *  We treat these largely like ASSERTION errors, but then translate them into a THROW of an exception - since that is
     *  probably more often the right thing todo.
     */
    void invalid_parameter_handler_ (const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
    {
        TraceContextBumper trcCtx{Stroika_Foundation_Debug_OptionalizeTraceArgs (L"invalid_parameter_handler", L"Func='%s', expr='%s', file='%s'.", function, expression, file)};
        Assert (false);
        Execution::Throw (Execution::Platform::Windows::Exception (ERROR_INVALID_PARAMETER));
    }
}
void Execution::Platform::Windows::RegisterDefaultHandler_invalid_parameter ()
{
    (void)_set_invalid_parameter_handler (invalid_parameter_handler_);
}
<|endoftext|>


<commit_before>#include <QtGui>
#include "Renderer.h"

const int IdRole = Qt::UserRole;

Renderer::Renderer(QWidget *parent)
    : QWidget(parent)
{
	// Initialize a couple variables
	hasPattern = false;
	hasImage = false;
    antialiased = true;
	gridX = 1;
	gridY = 1;
	outline = Qt::black;
	brush = Qt::white;

	this->setPalette(QPalette(this->backgroundRole(), Qt::white));
}

Renderer::~Renderer()
{
	if (hasImage)
	{
		hasImage = false;
	}
}

void Renderer::newImage(int x, int y)
{
	image = QImage(x,y,QImage::Format_RGB32);
	image.fill(brush.rgb());

	gridX = x;
	gridY = y;
	hasImage = true;

	updatePatternSize();
}

void Renderer::loadImage(QString imagePath)
{
	image.load(imagePath);
	if (!image.isNull())
	{
		gridX = image.width();
		gridY = image.height();
		//std::cout << "Image loaded: " << imagePath.toStdString() << " size: " << gridX << "x" << gridY << "\n";

		hasImage = true;
	}
	updatePatternSize();
}

void Renderer::setBackgroundColor(QColor color)
{
	this->setPalette(QPalette(this->backgroundRole(), color));
}

void Renderer::setOutlineColor(QColor color)
{
	outline = color;
}

void Renderer::setBrushColor(QColor color)
{
	brush = color;
}

void Renderer::rotateTranspose()
{
	rotate(QTransform(0,-1,-1,0,1,1));
}

void Renderer::rotateClockwise()
{
	rotate(QTransform(0,1,-1,0,1,1));
}

void Renderer::rotateCounterClockwise()
{
	rotate(QTransform(0,-1,1,0,1,1));
}

void Renderer::rotate180()
{
	rotate(QTransform(-1,0,0,-1,1,1));
}

void Renderer::rotateFlipX()
{
	rotate(QTransform(-1,0,0,1,1,1));
}

void Renderer::rotateFlipY()
{
	rotate(QTransform(1,0,0,-1,1,1));
}

void Renderer::zoomIn()
{
	zoom*=1.1;
	updatePatternSize();
}

void Renderer::zoomOut()
{
	zoom*=0.9;
	updatePatternSize();
}

void Renderer::zoomNormal()
{
	zoom=1.0;
	updatePatternSize();
}

void Renderer::setPattern(QDir dir)
{
	//std::cout << "Loaded Pattern: " << dir.dirName().toStdString() << "\n";
	pattern.loadPattern(dir);
	zoom = 1;
	hasPattern = true;
	updatePatternSize();
}

QSize Renderer::getMinSize()
{
	return QSize(sizeX,sizeY);

}

bool Renderer::saveImage(QString saveFileName)
{
	if (hasImage)
	{
		return image.save(saveFileName);
	}
	return false;
}

void Renderer::paintEvent(QPaintEvent *)
{
	QPainter painter(this);

	if (hasPattern && hasImage)
	{
		// Paint the outline background
		int x=0;
		int y=0;
		int gridCountX = int(gridX/pattern.getReadX());
		int gridCountY = int(gridY/pattern.getReadY());
		for (int i=0; i<=gridCountX+1; i++)
		{
			y=0;
			for (int j=0; j<=gridCountY+1; j++)
			{
				painter.save();
				painter.scale(zoom,zoom);
				painter.translate(x,y);
				painter.scale(zoom,zoom);

				painter.setPen(outline);
				painter.drawPixmap(0,0,QBitmap(pattern.getBackground()));

				painter.restore();
				y+=int(pattern.getY()*zoom);
			}
			x+=int(pattern.getX()*zoom);
		}

		// Paint the imageGrid
		x=0;
		y=0;
		for (int i=0; i<=gridCountX; i++)
		{
			y=0;
			for (int j=0; j<=gridCountY; j++)
			{
				painter.save();
				painter.scale(zoom,zoom);
				painter.translate(x,y);
				painter.scale(zoom,zoom);

				// Paint tiles
				for (int tileX=0; tileX < pattern.getReadX(); tileX++)
				{
					for (int tileY=0; tileY < pattern.getReadY(); tileY++)
					{
						int pixelX = i*(pattern.getReadX())+pattern.getTileReadX(tileX, tileY);
						int pixelY = j*(pattern.getReadY())+pattern.getTileReadY(tileX, tileY);
						if (pixelX < gridX && pixelY < gridY)
						{
							painter.setPen(image.pixel(pixelX, pixelY));
							painter.drawPixmap(pattern.getTileX(tileX, tileY),pattern.getTileY(tileX, tileY), QBitmap(pattern.getTile(tileX, tileY)));
						}
					}
				}
				painter.restore();
				y += int(pattern.getY()*zoom);
			}
			x += int(pattern.getX()*zoom);
		}
	}
	painter.end();
}

void Renderer::mousePressEvent(QMouseEvent *e)
{
	if (hasImage && hasPattern)
	{
		//std::cout << "Clicked: " << e->x() << ", " << e->y() << "\n";
		// Find the closest 4 grid locations and test tiles in area
		int xPos = int(e->x()*gridX/(pattern.getW()+pattern.getX()/pattern.getReadX()*(gridX-1))*zoom*zoom);
		int yPos = int(e->y()*gridY/(pattern.getH()+pattern.getY()/pattern.getReadY()*(gridY-1))*zoom*zoom);

		if (xPos<gridX && yPos<gridY)
		{
			image.setPixel(xPos,yPos,brush.rgb());
			update();
		}
	}
}

void Renderer::updatePatternSize()
{
	if (hasImage && hasPattern)
	{
		int gridXCount = int(gridX/pattern.getReadX());
		int gridYCount = int(gridY/pattern.getReadY());

		sizeX = int((pattern.getX()*gridXCount+pattern.getLargestTileOffsetX())*zoom*zoom);
		sizeY = int((pattern.getY()*gridYCount+pattern.getLargestTileOffsetY())*zoom*zoom);

		update();
	}
}

void Renderer::rotate(QTransform matrix)
{
	if (hasImage)
	{
		QImage newImage = image.transformed(matrix);
		image.swap(newImage);

		gridX = image.width();
		gridY = image.height();

		updatePatternSize();
	}
}

<commit_msg>Click to paint mask working<commit_after>#include <QtGui>
#include "Renderer.h"

const int IdRole = Qt::UserRole;

Renderer::Renderer(QWidget *parent)
    : QWidget(parent)
{
	// Initialize a couple variables
	hasPattern = false;
	hasImage = false;
    antialiased = true;
	gridX = 1;
	gridY = 1;
	outline = Qt::black;
	brush = Qt::white;

	this->setPalette(QPalette(this->backgroundRole(), Qt::white));
}

Renderer::~Renderer()
{
	if (hasImage)
	{
		hasImage = false;
	}
}

void Renderer::newImage(int x, int y)
{
	image = QImage(x,y,QImage::Format_RGB32);
	image.fill(brush.rgb());

	gridX = x;
	gridY = y;
	hasImage = true;

	updatePatternSize();
}

void Renderer::loadImage(QString imagePath)
{
	image.load(imagePath);
	if (!image.isNull())
	{
		gridX = image.width();
		gridY = image.height();
		//std::cout << "Image loaded: " << imagePath.toStdString() << " size: " << gridX << "x" << gridY << "\n";

		hasImage = true;
	}
	updatePatternSize();
}

void Renderer::setBackgroundColor(QColor color)
{
	this->setPalette(QPalette(this->backgroundRole(), color));
}

void Renderer::setOutlineColor(QColor color)
{
	outline = color;
}

void Renderer::setBrushColor(QColor color)
{
	brush = color;
}

void Renderer::rotateTranspose()
{
	rotate(QTransform(0,-1,-1,0,1,1));
}

void Renderer::rotateClockwise()
{
	rotate(QTransform(0,1,-1,0,1,1));
}

void Renderer::rotateCounterClockwise()
{
	rotate(QTransform(0,-1,1,0,1,1));
}

void Renderer::rotate180()
{
	rotate(QTransform(-1,0,0,-1,1,1));
}

void Renderer::rotateFlipX()
{
	rotate(QTransform(-1,0,0,1,1,1));
}

void Renderer::rotateFlipY()
{
	rotate(QTransform(1,0,0,-1,1,1));
}

void Renderer::zoomIn()
{
	zoom*=1.1;
	updatePatternSize();
}

void Renderer::zoomOut()
{
	zoom*=0.9;
	updatePatternSize();
}

void Renderer::zoomNormal()
{
	zoom=1.0;
	updatePatternSize();
}

void Renderer::setPattern(QDir dir)
{
	//std::cout << "Loaded Pattern: " << dir.dirName().toStdString() << "\n";
	pattern.loadPattern(dir);
	zoom = 1;
	hasPattern = true;
	updatePatternSize();
}

QSize Renderer::getMinSize()
{
	return QSize(sizeX,sizeY);

}

bool Renderer::saveImage(QString saveFileName)
{
	if (hasImage)
	{
		return image.save(saveFileName);
	}
	return false;
}

void Renderer::paintEvent(QPaintEvent *)
{
	QPainter painter(this);

	if (hasPattern && hasImage)
	{
		// Paint the outline background
		int x=0;
		int y=0;
		int gridCountX = int(gridX/pattern.getReadX());
		int gridCountY = int(gridY/pattern.getReadY());
		for (int i=0; i<=gridCountX+1; i++)
		{
			y=0;
			for (int j=0; j<=gridCountY+1; j++)
			{
				painter.save();
				painter.scale(zoom,zoom);
				painter.translate(x,y);
				painter.scale(zoom,zoom);

				painter.setPen(outline);
				painter.drawPixmap(0,0,QBitmap(pattern.getBackground()));

				painter.restore();
				y+=int(pattern.getY()*zoom);
			}
			x+=int(pattern.getX()*zoom);
		}

		// Paint the imageGrid
		x=0;
		y=0;
		for (int i=0; i<=gridCountX; i++)
		{
			y=0;
			for (int j=0; j<=gridCountY; j++)
			{
				painter.save();
				painter.scale(zoom,zoom);
				painter.translate(x,y);
				painter.scale(zoom,zoom);

				// Paint tiles
				for (int tileX=0; tileX < pattern.getReadX(); tileX++)
				{
					for (int tileY=0; tileY < pattern.getReadY(); tileY++)
					{
						int pixelX = i*(pattern.getReadX())+pattern.getTileReadX(tileX, tileY);
						int pixelY = j*(pattern.getReadY())+pattern.getTileReadY(tileX, tileY);
						if (pixelX < gridX && pixelY < gridY)
						{
							painter.setPen(image.pixel(pixelX, pixelY));
							painter.drawPixmap(pattern.getTileX(tileX, tileY),pattern.getTileY(tileX, tileY), QBitmap(pattern.getTile(tileX, tileY)));
						}
					}
				}
				painter.restore();
				y += int(pattern.getY()*zoom);
			}
			x += int(pattern.getX()*zoom);
		}
	}
	painter.end();
}

void Renderer::mousePressEvent(QMouseEvent *e)
{
	if (hasImage && hasPattern)
	{
		// Starting positions to test
		int eX = int(e->x()/zoom/zoom);
		int eY = int(e->y()/zoom/zoom);
		int startX = int(e->x()/zoom/zoom/pattern.getX());
		int startY = int(e->y()/zoom/zoom/pattern.getY());

		// Search 3x3 patterned area
		for (int i=-1; i<2; i++)
		{
			for (int j=-1; j<2; j++)
			{
				int curX = i+startX;
				int curY = j+startY;

				if (curX >= 0 && curX < gridX && curY >= 0 && curY < gridY)
				{
					// Search all subtiles
					for (int tileX=0; tileX<pattern.getReadX(); tileX++)
					{
						for (int tileY=0; tileY<pattern.getReadY(); tileY++)
						{
							QBitmap tile = pattern.getTile(tileX,tileY);
							int xTest = eX-(curX*pattern.getX()+pattern.getTileX(tileX,tileY));
							int yTest = eY-(curY*pattern.getY()+pattern.getTileY(tileX,tileY));
							if (tile.rect().contains(xTest,yTest))
							{
								// Check if clicked pixel is within tile mask
								if (QColor(tile.toImage().pixel(xTest,yTest)).black()>0)
								{
									int pixelX = curX*pattern.getReadX()+pattern.getTileReadX(tileX,tileY);
									int pixelY = curY*pattern.getReadY()+pattern.getTileReadY(tileX,tileY);
									// Make sure clicked image pixel is inside the image
									if (pixelX < gridX && pixelY < gridY)
									{
										image.setPixel(pixelX,pixelY,brush.rgb());
										update();
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

void Renderer::updatePatternSize()
{
	if (hasImage && hasPattern)
	{
		int gridXCount = int(gridX/pattern.getReadX());
		int gridYCount = int(gridY/pattern.getReadY());

		sizeX = int((pattern.getX()*gridXCount+pattern.getLargestTileOffsetX())*zoom*zoom);
		sizeY = int((pattern.getY()*gridYCount+pattern.getLargestTileOffsetY())*zoom*zoom);

		update();
	}
}

void Renderer::rotate(QTransform matrix)
{
	if (hasImage)
	{
		QImage newImage = image.transformed(matrix);
		image.swap(newImage);

		gridX = image.width();
		gridY = image.height();

		updatePatternSize();
	}
}

<|endoftext|>


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

#include    "../../../Foundation/Characters/String_Constant.h"
#include    "../../../Foundation/Characters/String2Float.h"
#include    "../../../Foundation/Characters/String2Int.h"
#include    "../../../Foundation/Containers/Mapping.h"
#include    "../../../Foundation/Containers/Sequence.h"
#include    "../../../Foundation/Containers/Set.h"
#include    "../../../Foundation/Debug/Assertions.h"
#include    "../../../Foundation/Debug/AssertExternallySynchronizedLock.h"
#include    "../../../Foundation/Debug/Trace.h"
#include    "../../../Foundation/DataExchange/CharacterDelimitedLines/Reader.h"
#include    "../../../Foundation/Execution/Sleep.h"
#include    "../../../Foundation/IO/FileSystem/BinaryFileInputStream.h"
#include    "../../../Foundation/Streams/BinaryInputStream.h"

#include    "../CommonMeasurementTypes.h"

#include    "Memory.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::Memory;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::SystemPerformance;

using   Characters::Character;
using   Characters::String_Constant;
using   Containers::Mapping;
using   Containers::Sequence;
using   Containers::Set;
using   IO::FileSystem::BinaryFileInputStream;
using   Time::DurationSecondsType;

using   Stroika::Frameworks::SystemPerformance::Instruments::Memory::Options;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

#ifndef qUseWMICollectionSupport_
#define qUseWMICollectionSupport_       qPlatform_Windows
#endif

#if     qUseWMICollectionSupport_
#include    "../Support/WMICollector.h"

using   SystemPerformance::Support::WMICollector;
#endif

#if     qUseWMICollectionSupport_
namespace {
    const   String_Constant     kInstanceName_      { L"_Total" };

    const   String_Constant     kCommittedBytes_    { L"Committed Bytes" };
    const   String_Constant     kCommitLimit_       { L"Commit Limit" };
    const   String_Constant     kPagesPerSec_       { L"Pages/sec" };           // hard page faults/sec
}
#endif

#if     qPlatform_POSIX
namespace {
    struct  CapturerWithContext_POSIX_ {
        uint64_t                    fSaved_MajorPageFaultsSinceBoot {};
        Time::DurationSecondsType   fSaved_MajorPageFaultsSinceBoot_At {};

        CapturerWithContext_POSIX_ (Options options)
        {
            if (options.fMinimumAveragingInterval > 0) {
                capture_ ();    // hack for side-effect of  updating aved_MajorPageFaultsSinc etc
                Execution::Sleep (options.fMinimumAveragingInterval);
            }
        }
        CapturerWithContext_POSIX_ (const CapturerWithContext_POSIX_&) = default;   // copy by value fine - no need to re-wait...

        Instruments::Memory::Info capture_ ()
        {
            Instruments::Memory::Info   result;
            Read_ProcMemInfo (&result);
            Read_ProcVMStat_ (&result);
            return result;
        }

        void    Read_ProcMemInfo (Instruments::Memory::Info* updateResult)
        {
            auto    ReadMemInfoLine_  = [] (Optional<uint64_t>* result, const String & n, const Sequence<String>& line) {
                if (line.size () >= 3 and line[0] == n) {
                    String  unit = line[2];
                    double  factor = (unit == L"kB") ? 1024 : 1;
                    *result = static_cast<uint64_t> (round (Characters::String2Float<double> (line[1]) * factor));
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                    DbgTrace (L"Set %s = %ld", n.c_str (), static_cast<long> (**result));
#endif
                }
            };
            static  const   String_Constant kProcMemInfoFileName_ { L"/proc/meminfo" };
            //const String_Constant kProcMemInfoFileName_ { L"c:\\Sandbox\\VMSharedFolder\\meminfo" };
            DataExchange::CharacterDelimitedLines::Reader reader {{ ':', ' ', '\t' }};
            // Note - /procfs files always unseekable
            for (Sequence<String> line : reader.ReadMatrix (BinaryFileInputStream::mk (kProcMemInfoFileName_, BinaryFileInputStream::eNotSeekable))) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                DbgTrace (L"***in Instruments::Memory::Info capture_ linesize=%d, line[0]=%s", line.size(), line.empty () ? L"" : line[0].c_str ());
#endif
                ReadMemInfoLine_ (&updateResult->fFreePhysicalMemory, String_Constant (L"MemFree"), line);
                ReadMemInfoLine_ (&updateResult->fTotalVirtualMemory, String_Constant (L"VmallocTotal"), line);
                ReadMemInfoLine_ (&updateResult->fCommitLimit, String_Constant (L"CommitLimit"), line);
                ReadMemInfoLine_ (&updateResult->fUsedVirtualMemory, String_Constant (L"VmallocUsed"), line);
                ReadMemInfoLine_ (&updateResult->fLargestAvailableVirtualChunk, String_Constant (L"VmallocChunk"), line);
            }
        }
        void    Read_ProcVMStat_ (Instruments::Memory::Info* updateResult)
        {
            auto    ReadVMStatLine_ = [] (Optional<uint64_t>* result, const String & n, const Sequence<String>& line) {
                if (line.size () >= 2 and line[0] == n) {
                    *result = Characters::String2Int<uint64_t> (line[1]);
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                    DbgTrace (L"Set %s = %ld", n.c_str (), static_cast<long> (**result));
#endif
                }
            };
            {
                static  const   String_Constant kProcVMStatFileName_ { L"/proc/vmstat" };
                Optional<uint64_t>  pgfault;
                // Note - /procfs files always unseekable
                DataExchange::CharacterDelimitedLines::Reader reader {{ ' ', '\t' }};
                for (Sequence<String> line : reader.ReadMatrix (BinaryFileInputStream::mk (kProcVMStatFileName_, BinaryFileInputStream::eNotSeekable))) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                    DbgTrace (L"***in Instruments::Memory::Info capture_ linesize=%d, line[0]=%s", line.size(), line.empty () ? L"" : line[0].c_str ());
#endif
                    ReadVMStatLine_ (&pgfault, String_Constant (L"pgfault"), line);
                    ReadVMStatLine_ (&updateResult->fMajorPageFaultsSinceBoot, String_Constant (L"pgmajfault"), line);
                }
                if (pgfault.IsPresent () and updateResult->fMajorPageFaultsSinceBoot.IsPresent ()) {
                    updateResult->fMinorPageFaultsSinceBoot = *pgfault - *updateResult->fMajorPageFaultsSinceBoot;
                }
                if (updateResult->fMajorPageFaultsSinceBoot.IsPresent ()) {
                    Time::DurationSecondsType   now = Time::GetTickCount ();
                    if (fSaved_MajorPageFaultsSinceBoot_At != 0) {
                        updateResult->fMajorPageFaultsPerSecond = (*updateResult->fMajorPageFaultsSinceBoot - fSaved_MajorPageFaultsSinceBoot) / (now - fSaved_MajorPageFaultsSinceBoot_At);
                    }
                    fSaved_MajorPageFaultsSinceBoot = *updateResult->fMajorPageFaultsSinceBoot;
                    fSaved_MajorPageFaultsSinceBoot_At = now;
                }
            }
        }
    };
}
#endif

#if     qPlatform_Windows
namespace {
    struct  CapturerWithContext_Windows_ {
#if     qUseWMICollectionSupport_
        WMICollector        fMemoryWMICollector_ { String_Constant { L"Memory" }, {kInstanceName_},  {kCommittedBytes_, kCommitLimit_, kPagesPerSec_ } };
        DurationSecondsType fMinTimeBeforeFirstCapture;
#endif

        CapturerWithContext_Windows_ (Options options)
#if     qUseWMICollectionSupport_
            :   fMinTimeBeforeFirstCapture (options.fMinimumAveragingInterval)
#endif
        {
#if     qUseWMICollectionSupport_
            fMemoryWMICollector_.Collect ();
            Execution::Sleep (options.fMinimumAveragingInterval);
#endif
        }
        CapturerWithContext_Windows_ (const CapturerWithContext_Windows_& from)
#if     qUseWMICollectionSupport_
            : fMemoryWMICollector_ (from.fMemoryWMICollector_)
            ,   fMinTimeBeforeFirstCapture (from.fMinTimeBeforeFirstCapture)
#endif
        {
#if   qUseWMICollectionSupport_
            fMemoryWMICollector_.Collect ();
            Execution::Sleep (fMinTimeBeforeFirstCapture);
#endif
        }

        Instruments::Memory::Info capture_ ()
        {
            Instruments::Memory::Info   result;
            Read_GlobalMemoryStatusEx_(&result);
#if     qUseWMICollectionSupport_
            Read_WMI_ (&result);
#endif
            return result;
        }
        void    Read_GlobalMemoryStatusEx_ (Instruments::Memory::Info* updateResult)
        {
            MEMORYSTATUSEX statex;
            memset (&statex, 0, sizeof (statex));
            statex.dwLength = sizeof (statex);
            Verify (::GlobalMemoryStatusEx (&statex) != 0);
            updateResult->fFreePhysicalMemory = statex.ullAvailPhys;
        }
#if     qUseWMICollectionSupport_
        void    Read_WMI_ (Instruments::Memory::Info* updateResult)
        {
            fMemoryWMICollector_.Collect ();
            {
                if (auto o = fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kCommittedBytes_)) {
                    updateResult->fUsedVirtualMemory = *o ;
                }
                if (auto o = fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kCommitLimit_)) {
                    updateResult->fCommitLimit = *o ;
                    // bad names - RETHINK
                    updateResult->fTotalVirtualMemory = *o ;
                }
                if (auto o = fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kPagesPerSec_)) {
                    updateResult->fMajorPageFaultsPerSecond = *o ;
                }
            }
        }
#endif
    };
}
#endif

namespace {
    struct  CapturerWithContext_
            : Debug::AssertExternallySynchronizedLock
#if     qPlatform_POSIX
            , CapturerWithContext_POSIX_
#elif   qPlatform_Windows
            , CapturerWithContext_Windows_
#endif
    {
#if     qPlatform_POSIX
        using inherited = CapturerWithContext_POSIX_;
#elif   qPlatform_Windows
        using inherited = CapturerWithContext_Windows_;
#endif
        CapturerWithContext_ (Options options)
            : inherited (options)
        {
        }
        Instruments::Memory::Info capture_ ()
        {
            lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            Debug::TraceContextBumper ctx ("Instruments::Memory::Info capture_");
#endif
            return inherited::capture_ ();
        }
    };
}

const   MeasurementType Instruments::Memory::kSystemMemoryMeasurement = MeasurementType (String_Constant (L"System-Memory"));

/*
 ********************************************************************************
 ******************** Instruments::Memory::GetObjectVariantMapper ***************
 ********************************************************************************
 */
ObjectVariantMapper Instruments::Memory::GetObjectVariantMapper ()
{
    using   StructureFieldInfo = ObjectVariantMapper::StructureFieldInfo;
    ObjectVariantMapper sMapper_ = [] () -> ObjectVariantMapper {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<Optional<uint64_t>> ();
        mapper.AddCommonType<Optional<double>> ();
        DISABLE_COMPILER_CLANG_WARNING_START("clang diagnostic ignored \"-Winvalid-offsetof\"");   // Really probably an issue, but not to debug here -- LGP 2014-01-04
        DISABLE_COMPILER_GCC_WARNING_START("GCC diagnostic ignored \"-Winvalid-offsetof\"");       // Really probably an issue, but not to debug here -- LGP 2014-01-04
        mapper.AddClass<Info> (initializer_list<StructureFieldInfo> {
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fFreePhysicalMemory), String_Constant (L"Free-Physical-Memory") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fTotalVirtualMemory), String_Constant (L"Total-Virtual-Memory") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fCommitLimit), String_Constant (L"Commit-Limit") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fUsedVirtualMemory), String_Constant (L"Used-Virtual-Memory") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fLargestAvailableVirtualChunk), String_Constant (L"Largest-Available-Virtual-Chunk") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMajorPageFaultsSinceBoot), String_Constant (L"Major-Page-Faults-Since-Boot") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMinorPageFaultsSinceBoot), String_Constant (L"Minor-Page-Faults-Since-Boot") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMajorPageFaultsPerSecond), String_Constant (L"Major-Page-Faults-Per-Second") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMinorPageFaultsPerSecond), String_Constant (L"Minor-Page-Faults-Per-Second") },
        });
        DISABLE_COMPILER_GCC_WARNING_END("GCC diagnostic ignored \"-Winvalid-offsetof\"");
        DISABLE_COMPILER_CLANG_WARNING_END("clang diagnostic ignored \"-Winvalid-offsetof\"");
        return mapper;
    } ();
    return sMapper_;
}

/*
 ********************************************************************************
 ******************* Instruments::Memory::GetInstrument *************************
 ********************************************************************************
 */
Instrument  SystemPerformance::Instruments::Memory::GetInstrument (Options options)
{
    CapturerWithContext_ useCaptureContext { options };  // capture context so copyable in mutable lambda
    static  const   Instrument  kInstrument_    = Instrument (
                InstrumentNameType (String_Constant (L"Memory")),
    [useCaptureContext] () mutable -> MeasurementSet {
        MeasurementSet    results;
        DateTime    before = DateTime::Now ();
        Instruments::Memory::Info rawMeasurement = useCaptureContext.capture_ ();
        results.fMeasuredAt = DateTimeRange (before, DateTime::Now ());
        Measurement m;
        m.fValue = GetObjectVariantMapper ().FromObject (rawMeasurement);
        m.fType = kSystemMemoryMeasurement;
        results.fMeasurements.Add (m);
        return results;
    },
    {kMemoryUsage},
    GetObjectVariantMapper ()
            );
    return kInstrument_;
}
<commit_msg>use CopyToIf() to cleanup some code<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2015.  All rights reserved
 */
#include    "../../StroikaPreComp.h"

#include    "../../../Foundation/Characters/String_Constant.h"
#include    "../../../Foundation/Characters/String2Float.h"
#include    "../../../Foundation/Characters/String2Int.h"
#include    "../../../Foundation/Containers/Mapping.h"
#include    "../../../Foundation/Containers/Sequence.h"
#include    "../../../Foundation/Containers/Set.h"
#include    "../../../Foundation/Debug/Assertions.h"
#include    "../../../Foundation/Debug/AssertExternallySynchronizedLock.h"
#include    "../../../Foundation/Debug/Trace.h"
#include    "../../../Foundation/DataExchange/CharacterDelimitedLines/Reader.h"
#include    "../../../Foundation/Execution/Sleep.h"
#include    "../../../Foundation/IO/FileSystem/BinaryFileInputStream.h"
#include    "../../../Foundation/Streams/BinaryInputStream.h"

#include    "../CommonMeasurementTypes.h"

#include    "Memory.h"

using   namespace   Stroika::Foundation;
using   namespace   Stroika::Foundation::Containers;
using   namespace   Stroika::Foundation::DataExchange;
using   namespace   Stroika::Foundation::Memory;

using   namespace   Stroika::Frameworks;
using   namespace   Stroika::Frameworks::SystemPerformance;

using   Characters::Character;
using   Characters::String_Constant;
using   Containers::Mapping;
using   Containers::Sequence;
using   Containers::Set;
using   IO::FileSystem::BinaryFileInputStream;
using   Time::DurationSecondsType;

using   Stroika::Frameworks::SystemPerformance::Instruments::Memory::Options;

// Comment this in to turn on aggressive noisy DbgTrace in this module
//#define   USE_NOISY_TRACE_IN_THIS_MODULE_       1

#ifndef qUseWMICollectionSupport_
#define qUseWMICollectionSupport_       qPlatform_Windows
#endif

#if     qUseWMICollectionSupport_
#include    "../Support/WMICollector.h"

using   SystemPerformance::Support::WMICollector;
#endif

#if     qUseWMICollectionSupport_
namespace {
    const   String_Constant     kInstanceName_      { L"_Total" };

    const   String_Constant     kCommittedBytes_    { L"Committed Bytes" };
    const   String_Constant     kCommitLimit_       { L"Commit Limit" };
    const   String_Constant     kPagesPerSec_       { L"Pages/sec" };           // hard page faults/sec
}
#endif

#if     qPlatform_POSIX
namespace {
    struct  CapturerWithContext_POSIX_ {
        uint64_t                    fSaved_MajorPageFaultsSinceBoot {};
        Time::DurationSecondsType   fSaved_MajorPageFaultsSinceBoot_At {};

        CapturerWithContext_POSIX_ (Options options)
        {
            if (options.fMinimumAveragingInterval > 0) {
                capture_ ();    // hack for side-effect of  updating aved_MajorPageFaultsSinc etc
                Execution::Sleep (options.fMinimumAveragingInterval);
            }
        }
        CapturerWithContext_POSIX_ (const CapturerWithContext_POSIX_&) = default;   // copy by value fine - no need to re-wait...

        Instruments::Memory::Info capture_ ()
        {
            Instruments::Memory::Info   result;
            Read_ProcMemInfo (&result);
            Read_ProcVMStat_ (&result);
            return result;
        }

        void    Read_ProcMemInfo (Instruments::Memory::Info* updateResult)
        {
            auto    ReadMemInfoLine_  = [] (Optional<uint64_t>* result, const String & n, const Sequence<String>& line) {
                if (line.size () >= 3 and line[0] == n) {
                    String  unit = line[2];
                    double  factor = (unit == L"kB") ? 1024 : 1;
                    *result = static_cast<uint64_t> (round (Characters::String2Float<double> (line[1]) * factor));
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                    DbgTrace (L"Set %s = %ld", n.c_str (), static_cast<long> (**result));
#endif
                }
            };
            static  const   String_Constant kProcMemInfoFileName_ { L"/proc/meminfo" };
            //const String_Constant kProcMemInfoFileName_ { L"c:\\Sandbox\\VMSharedFolder\\meminfo" };
            DataExchange::CharacterDelimitedLines::Reader reader {{ ':', ' ', '\t' }};
            // Note - /procfs files always unseekable
            for (Sequence<String> line : reader.ReadMatrix (BinaryFileInputStream::mk (kProcMemInfoFileName_, BinaryFileInputStream::eNotSeekable))) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                DbgTrace (L"***in Instruments::Memory::Info capture_ linesize=%d, line[0]=%s", line.size(), line.empty () ? L"" : line[0].c_str ());
#endif
                ReadMemInfoLine_ (&updateResult->fFreePhysicalMemory, String_Constant (L"MemFree"), line);
                ReadMemInfoLine_ (&updateResult->fTotalVirtualMemory, String_Constant (L"VmallocTotal"), line);
                ReadMemInfoLine_ (&updateResult->fCommitLimit, String_Constant (L"CommitLimit"), line);
                ReadMemInfoLine_ (&updateResult->fUsedVirtualMemory, String_Constant (L"VmallocUsed"), line);
                ReadMemInfoLine_ (&updateResult->fLargestAvailableVirtualChunk, String_Constant (L"VmallocChunk"), line);
            }
        }
        void    Read_ProcVMStat_ (Instruments::Memory::Info* updateResult)
        {
            auto    ReadVMStatLine_ = [] (Optional<uint64_t>* result, const String & n, const Sequence<String>& line) {
                if (line.size () >= 2 and line[0] == n) {
                    *result = Characters::String2Int<uint64_t> (line[1]);
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                    DbgTrace (L"Set %s = %ld", n.c_str (), static_cast<long> (**result));
#endif
                }
            };
            {
                static  const   String_Constant kProcVMStatFileName_ { L"/proc/vmstat" };
                Optional<uint64_t>  pgfault;
                // Note - /procfs files always unseekable
                DataExchange::CharacterDelimitedLines::Reader reader {{ ' ', '\t' }};
                for (Sequence<String> line : reader.ReadMatrix (BinaryFileInputStream::mk (kProcVMStatFileName_, BinaryFileInputStream::eNotSeekable))) {
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
                    DbgTrace (L"***in Instruments::Memory::Info capture_ linesize=%d, line[0]=%s", line.size(), line.empty () ? L"" : line[0].c_str ());
#endif
                    ReadVMStatLine_ (&pgfault, String_Constant (L"pgfault"), line);
                    ReadVMStatLine_ (&updateResult->fMajorPageFaultsSinceBoot, String_Constant (L"pgmajfault"), line);
                }
                if (pgfault.IsPresent () and updateResult->fMajorPageFaultsSinceBoot.IsPresent ()) {
                    updateResult->fMinorPageFaultsSinceBoot = *pgfault - *updateResult->fMajorPageFaultsSinceBoot;
                }
                if (updateResult->fMajorPageFaultsSinceBoot.IsPresent ()) {
                    Time::DurationSecondsType   now = Time::GetTickCount ();
                    if (fSaved_MajorPageFaultsSinceBoot_At != 0) {
                        updateResult->fMajorPageFaultsPerSecond = (*updateResult->fMajorPageFaultsSinceBoot - fSaved_MajorPageFaultsSinceBoot) / (now - fSaved_MajorPageFaultsSinceBoot_At);
                    }
                    fSaved_MajorPageFaultsSinceBoot = *updateResult->fMajorPageFaultsSinceBoot;
                    fSaved_MajorPageFaultsSinceBoot_At = now;
                }
            }
        }
    };
}
#endif

#if     qPlatform_Windows
namespace {
    struct  CapturerWithContext_Windows_ {
#if     qUseWMICollectionSupport_
        WMICollector        fMemoryWMICollector_ { String_Constant { L"Memory" }, {kInstanceName_},  {kCommittedBytes_, kCommitLimit_, kPagesPerSec_ } };
        DurationSecondsType fMinTimeBeforeFirstCapture;
#endif

        CapturerWithContext_Windows_ (Options options)
#if     qUseWMICollectionSupport_
            :   fMinTimeBeforeFirstCapture (options.fMinimumAveragingInterval)
#endif
        {
#if     qUseWMICollectionSupport_
            fMemoryWMICollector_.Collect ();
            Execution::Sleep (options.fMinimumAveragingInterval);
#endif
        }
        CapturerWithContext_Windows_ (const CapturerWithContext_Windows_& from)
#if     qUseWMICollectionSupport_
            : fMemoryWMICollector_ (from.fMemoryWMICollector_)
            ,   fMinTimeBeforeFirstCapture (from.fMinTimeBeforeFirstCapture)
#endif
        {
#if   qUseWMICollectionSupport_
            fMemoryWMICollector_.Collect ();
            Execution::Sleep (fMinTimeBeforeFirstCapture);
#endif
        }

        Instruments::Memory::Info capture_ ()
        {
            Instruments::Memory::Info   result;
            Read_GlobalMemoryStatusEx_(&result);
#if     qUseWMICollectionSupport_
            Read_WMI_ (&result);
#endif
            return result;
        }
        void    Read_GlobalMemoryStatusEx_ (Instruments::Memory::Info* updateResult)
        {
            MEMORYSTATUSEX statex;
            memset (&statex, 0, sizeof (statex));
            statex.dwLength = sizeof (statex);
            Verify (::GlobalMemoryStatusEx (&statex) != 0);
            updateResult->fFreePhysicalMemory = statex.ullAvailPhys;
        }
#if     qUseWMICollectionSupport_
        void    Read_WMI_ (Instruments::Memory::Info* updateResult)
        {
            fMemoryWMICollector_.Collect ();
            fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kCommittedBytes_).CopyToIf (&updateResult->fUsedVirtualMemory);
            fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kCommitLimit_).CopyToIf (&updateResult->fCommitLimit);
            fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kCommitLimit_).CopyToIf (&updateResult->fTotalVirtualMemory);        // bad names - RETHINK
            fMemoryWMICollector_.PeekCurrentValue (kInstanceName_, kPagesPerSec_).CopyToIf (&updateResult->fMajorPageFaultsPerSecond);
        }
#endif
    };
}
#endif

namespace {
    struct  CapturerWithContext_
            : Debug::AssertExternallySynchronizedLock
#if     qPlatform_POSIX
            , CapturerWithContext_POSIX_
#elif   qPlatform_Windows
            , CapturerWithContext_Windows_
#endif
    {
#if     qPlatform_POSIX
        using inherited = CapturerWithContext_POSIX_;
#elif   qPlatform_Windows
        using inherited = CapturerWithContext_Windows_;
#endif
        CapturerWithContext_ (Options options)
            : inherited (options)
        {
        }
        Instruments::Memory::Info capture_ ()
        {
            lock_guard<const AssertExternallySynchronizedLock> critSec { *this };
#if     USE_NOISY_TRACE_IN_THIS_MODULE_
            Debug::TraceContextBumper ctx ("Instruments::Memory::Info capture_");
#endif
            return inherited::capture_ ();
        }
    };
}

const   MeasurementType Instruments::Memory::kSystemMemoryMeasurement = MeasurementType (String_Constant (L"System-Memory"));

/*
 ********************************************************************************
 ******************** Instruments::Memory::GetObjectVariantMapper ***************
 ********************************************************************************
 */
ObjectVariantMapper Instruments::Memory::GetObjectVariantMapper ()
{
    using   StructureFieldInfo = ObjectVariantMapper::StructureFieldInfo;
    ObjectVariantMapper sMapper_ = [] () -> ObjectVariantMapper {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<Optional<uint64_t>> ();
        mapper.AddCommonType<Optional<double>> ();
        DISABLE_COMPILER_CLANG_WARNING_START("clang diagnostic ignored \"-Winvalid-offsetof\"");   // Really probably an issue, but not to debug here -- LGP 2014-01-04
        DISABLE_COMPILER_GCC_WARNING_START("GCC diagnostic ignored \"-Winvalid-offsetof\"");       // Really probably an issue, but not to debug here -- LGP 2014-01-04
        mapper.AddClass<Info> (initializer_list<StructureFieldInfo> {
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fFreePhysicalMemory), String_Constant (L"Free-Physical-Memory") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fTotalVirtualMemory), String_Constant (L"Total-Virtual-Memory") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fCommitLimit), String_Constant (L"Commit-Limit") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fUsedVirtualMemory), String_Constant (L"Used-Virtual-Memory") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fLargestAvailableVirtualChunk), String_Constant (L"Largest-Available-Virtual-Chunk") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMajorPageFaultsSinceBoot), String_Constant (L"Major-Page-Faults-Since-Boot") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMinorPageFaultsSinceBoot), String_Constant (L"Minor-Page-Faults-Since-Boot") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMajorPageFaultsPerSecond), String_Constant (L"Major-Page-Faults-Per-Second") },
            { Stroika_Foundation_DataExchange_ObjectVariantMapper_FieldInfoKey (Info, fMinorPageFaultsPerSecond), String_Constant (L"Minor-Page-Faults-Per-Second") },
        });
        DISABLE_COMPILER_GCC_WARNING_END("GCC diagnostic ignored \"-Winvalid-offsetof\"");
        DISABLE_COMPILER_CLANG_WARNING_END("clang diagnostic ignored \"-Winvalid-offsetof\"");
        return mapper;
    } ();
    return sMapper_;
}

/*
 ********************************************************************************
 ******************* Instruments::Memory::GetInstrument *************************
 ********************************************************************************
 */
Instrument  SystemPerformance::Instruments::Memory::GetInstrument (Options options)
{
    CapturerWithContext_ useCaptureContext { options };  // capture context so copyable in mutable lambda
    static  const   Instrument  kInstrument_    = Instrument (
                InstrumentNameType (String_Constant (L"Memory")),
    [useCaptureContext] () mutable -> MeasurementSet {
        MeasurementSet    results;
        DateTime    before = DateTime::Now ();
        Instruments::Memory::Info rawMeasurement = useCaptureContext.capture_ ();
        results.fMeasuredAt = DateTimeRange (before, DateTime::Now ());
        Measurement m;
        m.fValue = GetObjectVariantMapper ().FromObject (rawMeasurement);
        m.fType = kSystemMemoryMeasurement;
        results.fMeasurements.Add (m);
        return results;
    },
    {kMemoryUsage},
    GetObjectVariantMapper ()
            );
    return kInstrument_;
}
<|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 <iostream>

#include "itkImage.h"
#include "itkGaussianInterpolateImageFunction.h"
#include "itkMath.h"
#include "itkTestingMacros.h"

int itkGaussianInterpolateImageFunctionTest( int, char*[] )
{
  using ImageType = itk::Image< float, 2 >;
  using InterpolatorType = itk::GaussianInterpolateImageFunction< ImageType, float >;

  InterpolatorType::Pointer interpolator = InterpolatorType::New();

  EXERCISE_BASIC_OBJECT_METHODS( interpolator, GaussianInterpolateImageFunction, InterpolateImageFunction );

  InterpolatorType::ArrayType sigma;
  sigma.Fill(1.0);
  interpolator->SetSigma(sigma);
  TEST_SET_GET_VALUE( sigma, interpolator->GetSigma() );

  InterpolatorType::RealType alpha = 1.0;
  interpolator->SetAlpha(alpha);
  TEST_SET_GET_VALUE( alpha, interpolator->GetAlpha() );

  ImageType::Pointer image = ImageType::New();

  ImageType::IndexType start;
  start.Fill(0);

  ImageType::SizeType size;
  size.Fill(3);

  ImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(start);

  image->SetRegions(region);
  image->Allocate();

  ImageType::PointType origin;
  ImageType::SpacingType spacing;

  origin.Fill(0.0);
  spacing.Fill(1.0);

  image->SetOrigin(origin);
  image->SetSpacing(spacing);

  for ( unsigned int i = 0; i < 3; ++i )
  {
    for ( unsigned int j = 0; j < 3; ++j )
    {
      image->SetPixel({{i, j}}, i + j);
    }
  }

  interpolator->SetInputImage(image);

  InterpolatorType::OutputType expectedValues[5][5] = {{0.773964, 0.886982, 1.38698, 1.88698, 2.0},
    {0.886982, 1.0, 1.5, 2.0, 2.11302},
    {1.38698, 1.5, 2.0, 2.5, 2.61302},
    {1.88698, 2.0, 2.5, 3.0, 3.11302},
    {2.0, 2.11302, 2.61302, 3.11302, 3.22604}};

  ImageType::PointType point;
  point[0] = 0.0;

  for ( unsigned int i = 0; i < 5; ++i )
  {
    point[1] = 0.0;

    for ( unsigned int j = 0; j < 5; ++j )
    {
      InterpolatorType::OutputType computedValue = interpolator->Evaluate(point);

      if ( ! itk::Math::FloatAlmostEqual(computedValue, expectedValues[i][j], 7, 5e-6) )
      {
        std::cerr << "Error: computed and expected values are different" << std::endl;
        std::cerr << "Point: " << point << std::endl;
        std::cerr << "Computed: " << computedValue << std::endl;
        std::cerr << "Expectd: " << expectedValues[i][j] << std::endl;
        return EXIT_FAILURE;
      }

      point[1] += 0.5;
    }

    point[0] += 0.5;
  }

  return EXIT_SUCCESS;
}
<commit_msg>STYLE: Visually indent array<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 <iostream>

#include "itkImage.h"
#include "itkGaussianInterpolateImageFunction.h"
#include "itkMath.h"
#include "itkTestingMacros.h"

int itkGaussianInterpolateImageFunctionTest( int, char*[] )
{
  using ImageType = itk::Image< float, 2 >;
  using InterpolatorType = itk::GaussianInterpolateImageFunction< ImageType, float >;

  InterpolatorType::Pointer interpolator = InterpolatorType::New();

  EXERCISE_BASIC_OBJECT_METHODS( interpolator, GaussianInterpolateImageFunction, InterpolateImageFunction );

  InterpolatorType::ArrayType sigma;
  sigma.Fill(1.0);
  interpolator->SetSigma(sigma);
  TEST_SET_GET_VALUE( sigma, interpolator->GetSigma() );

  InterpolatorType::RealType alpha = 1.0;
  interpolator->SetAlpha(alpha);
  TEST_SET_GET_VALUE( alpha, interpolator->GetAlpha() );

  ImageType::Pointer image = ImageType::New();

  ImageType::IndexType start;
  start.Fill(0);

  ImageType::SizeType size;
  size.Fill(3);

  ImageType::RegionType region;
  region.SetSize(size);
  region.SetIndex(start);

  image->SetRegions(region);
  image->Allocate();

  ImageType::PointType origin;
  ImageType::SpacingType spacing;

  origin.Fill(0.0);
  spacing.Fill(1.0);

  image->SetOrigin(origin);
  image->SetSpacing(spacing);

  for ( unsigned int i = 0; i < 3; ++i )
  {
    for ( unsigned int j = 0; j < 3; ++j )
    {
      image->SetPixel({{i, j}}, i + j);
    }
  }

  interpolator->SetInputImage(image);

  InterpolatorType::OutputType expectedValues[5][5] =
    {{0.773964, 0.886982, 1.38698, 1.88698, 2.0},
     {0.886982, 1.0,      1.5,     2.0,     2.11302},
     {1.38698,  1.5,      2.0,     2.5,     2.61302},
     {1.88698,  2.0,      2.5,     3.0,     3.11302},
     {2.0,      2.11302,  2.61302, 3.11302, 3.22604}};

  ImageType::PointType point;
  point[0] = 0.0;

  for ( unsigned int i = 0; i < 5; ++i )
  {
    point[1] = 0.0;

    for ( unsigned int j = 0; j < 5; ++j )
    {
      InterpolatorType::OutputType computedValue = interpolator->Evaluate(point);

      if ( ! itk::Math::FloatAlmostEqual(computedValue, expectedValues[i][j], 7, 5e-6) )
      {
        std::cerr << "Error: computed and expected values are different" << std::endl;
        std::cerr << "Point: " << point << std::endl;
        std::cerr << "Computed: " << computedValue << std::endl;
        std::cerr << "Expectd: " << expectedValues[i][j] << std::endl;
        return EXIT_FAILURE;
      }

      point[1] += 0.5;
    }

    point[0] += 0.5;
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#ifndef FILEPARSER_H
#define FILEPARSER_H

#include "common.hpp"
#include "fileinfo.hpp"
#include <fstream>
#include <memory>
#include <boost/algorithm/string.hpp>
#include <cassert>
#include <map>

class FileParser {
public:
    FileParser():
        singleToken(""),
        multiStartToken(""),
        multiEndToken(""),
        isSingleLine(false),
        isMultiLine(false)
    { }

    FileParser(const string& singleToken):
        singleToken(singleToken),
        multiStartToken(""),
        multiEndToken("") {
        isSingleLine = true;
        isMultiLine = false;
    }

    FileParser(const string& multiStartToken, const string& multiEndToken):
        multiStartToken(multiStartToken),
        multiEndToken(multiEndToken),
        singleToken("") {
        isSingleLine = false;
        isMultiLine = true;
    }

    FileParser(const string& multiStartToken, const string& multiEndToken, const string& singleToken):
        singleToken(singleToken),
        multiStartToken(multiStartToken),
        multiEndToken(multiEndToken) {
        isSingleLine = true;
        isMultiLine = true;
    }

    FileInfo parse(const file::path& path) {
        std::ifstream file(path.generic_string());
        string line;
        FileInfo info;
        bool multiLine = false;

        if(file) {
            while(std::getline(file, line)) {
                boost::trim(line);

                LineType result;
                if (isSingleLine) {
                    result = parseSingleLine(line);
                }
                if (isMultiLine) {
                    result = parseMultiLine(line, multiLine);
                }

                switch(result) {
                case SINGLE_LINE_COMMENT:
                case MULTI_LINE_COMMENT:
                case MULTI_LINE_COMMENT_END:
                case MULTI_LINE_COMMENT_START:
                    info.incSourceLines();
                    break;
                case SOURCE_LINE:
                    info.incSourceLines();
                    break;
                case BLANK_LINE:
                    info.incBlankLines();
                    break;
                default:
                    assert(0);
                }
            }
        }

        return info;
    }

private:
    string singleToken;
    string multiStartToken;
    string multiEndToken;
    bool isSingleLine;
    bool isMultiLine;

    enum LineType {
        SINGLE_LINE_COMMENT,
        SOURCE_LINE,
        BLANK_LINE,
        MULTI_LINE_COMMENT_START,
        MULTI_LINE_COMMENT,
        MULTI_LINE_COMMENT_END
    };

    LineType parseSingleLine(const string& line) {
        if (boost::starts_with(line, singleToken)) {
            return SINGLE_LINE_COMMENT;
        }

        if (line == "") {
            return BLANK_LINE;
        }

        return SOURCE_LINE;
    }

    LineType parseMultiLine(const string& line, bool& currentlyMultiLine) {
        if (currentlyMultiLine) {
            if (boost::find_first(line, multiEndToken)) {
                currentlyMultiLine = false;
                return MULTI_LINE_COMMENT_END;
            }
            else {
                return MULTI_LINE_COMMENT;
            }
        }
        else if (boost::starts_with(line, multiStartToken)) {
            if (!boost::find_first(line, multiEndToken)) {
                currentlyMultiLine = true;
            }
            return MULTI_LINE_COMMENT_START;
        }
        else if (line == "") {
            return BLANK_LINE;
        }

        return SOURCE_LINE;
    }

};

class FileParserFactory {
public:
    static FileParser& makeFileParser(const file::path& path);

    static vector<string> getExtensions();

private:
    static vector<string> cExts;
    static vector<string> lispExts;
    static std::map<string, FileParser> parsers;

    static void init();
    static bool isInitialized;
};

#endif // FILEPARSER_H
<commit_msg>Only trimming the left part of each line<commit_after>#ifndef FILEPARSER_H
#define FILEPARSER_H

#include "common.hpp"
#include "fileinfo.hpp"
#include <fstream>
#include <memory>
#include <boost/algorithm/string.hpp>
#include <cassert>
#include <map>

class FileParser {
public:
    FileParser():
        singleToken(""),
        multiStartToken(""),
        multiEndToken(""),
        isSingleLine(false),
        isMultiLine(false)
    { }

    FileParser(const string& singleToken):
        singleToken(singleToken),
        multiStartToken(""),
        multiEndToken("") {
        isSingleLine = true;
        isMultiLine = false;
    }

    FileParser(const string& multiStartToken, const string& multiEndToken):
        multiStartToken(multiStartToken),
        multiEndToken(multiEndToken),
        singleToken("") {
        isSingleLine = false;
        isMultiLine = true;
    }

    FileParser(const string& multiStartToken, const string& multiEndToken, const string& singleToken):
        singleToken(singleToken),
        multiStartToken(multiStartToken),
        multiEndToken(multiEndToken) {
        isSingleLine = true;
        isMultiLine = true;
    }

    FileInfo parse(const file::path& path) {
        std::ifstream file(path.generic_string());
        string line;
        FileInfo info;
        bool multiLine = false;

        if(file) {
            while(std::getline(file, line)) {
                boost::trim_left(line);

                LineType result;
                if (isSingleLine) {
                    result = parseSingleLine(line);
                }
                if (isMultiLine) {
                    result = parseMultiLine(line, multiLine);
                }

                switch(result) {
                case SINGLE_LINE_COMMENT:
                case MULTI_LINE_COMMENT:
                case MULTI_LINE_COMMENT_END:
                case MULTI_LINE_COMMENT_START:
                    info.incSourceLines();
                    break;
                case SOURCE_LINE:
                    info.incSourceLines();
                    break;
                case BLANK_LINE:
                    info.incBlankLines();
                    break;
                default:
                    assert(0);
                }
            }
        }

        return info;
    }

private:
    string singleToken;
    string multiStartToken;
    string multiEndToken;
    bool isSingleLine;
    bool isMultiLine;

    enum LineType {
        SINGLE_LINE_COMMENT,
        SOURCE_LINE,
        BLANK_LINE,
        MULTI_LINE_COMMENT_START,
        MULTI_LINE_COMMENT,
        MULTI_LINE_COMMENT_END
    };

    LineType parseSingleLine(const string& line) {
        if (boost::starts_with(line, singleToken)) {
            return SINGLE_LINE_COMMENT;
        }

        if (line == "") {
            return BLANK_LINE;
        }

        return SOURCE_LINE;
    }

    LineType parseMultiLine(const string& line, bool& currentlyMultiLine) {
        if (currentlyMultiLine) {
            if (boost::find_first(line, multiEndToken)) {
                currentlyMultiLine = false;
                return MULTI_LINE_COMMENT_END;
            }
            else {
                return MULTI_LINE_COMMENT;
            }
        }
        else if (boost::starts_with(line, multiStartToken)) {
            if (!boost::find_first(line, multiEndToken)) {
                currentlyMultiLine = true;
            }
            return MULTI_LINE_COMMENT_START;
        }
        else if (line == "") {
            return BLANK_LINE;
        }

        return SOURCE_LINE;
    }

};

class FileParserFactory {
public:
    static FileParser& makeFileParser(const file::path& path);

    static vector<string> getExtensions();

private:
    static vector<string> cExts;
    static vector<string> lispExts;
    static std::map<string, FileParser> parsers;

    static void init();
    static bool isInitialized;
};

#endif // FILEPARSER_H
<|endoftext|>