<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 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
 *
 *****************************************************************************/

#ifndef GDAL_DATASOURCE_MMAP_HPP
#define GDAL_DATASOURCE_MMAP_HPP

#include <mapnik/util/fs.hpp>
#include <mapnik/make_unique.hpp>
#include <mapnik/debug.hpp>

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/filesystem.hpp>

#include <gdal_priv.h>

struct mmapped_vsifile
{
    mmapped_vsifile(std::string const& filepath)
        : mapping(filepath.c_str(), boost::interprocess::read_only),
          region(mapping, boost::interprocess::read_only)
    {
        boost::filesystem::path vsimem("/vsimem");
        vsimem /= filepath;

        virt_file = VSIFileFromMemBuffer(
            vsimem.string().c_str(),
            static_cast<GByte*>(region.get_address()),
            region.get_size(),
            false);

        if (virt_file == NULL)
        {
            throw std::runtime_error("Call to VSIFileFromMemBuffer "
                "failed with '" + vsimem.string() + "'");
        }

        name = vsimem.string();
    }

    ~mmapped_vsifile()
    {
        VSIFCloseL(virt_file);
    }

    boost::interprocess::file_mapping mapping;
    boost::interprocess::mapped_region region;
    VSILFILE * virt_file;
    std::string name;
};

struct mmapped_tiff_dataset
{
    mmapped_tiff_dataset(std::string const& filepath)
        : tiff_file_mapping(filepath),
          overviews_file_mapping()
    {
        std::string ovr_file_name = filepath + ".ovr";
        if (mapnik::util::exists(ovr_file_name))
        {
            try
            {
                overviews_file_mapping = std::make_unique<mmapped_vsifile>(
                    ovr_file_name);
            }
            catch (std::exception const& e)
            {
                MAPNIK_LOG_ERROR(mmapped_tiff_dataset) <<
                    "gdal_datasource: Cannot mmap() "
                    " overviews file '" << ovr_file_name <<
                    "': " << e.what();
            }
        }
    }

    mmapped_vsifile tiff_file_mapping;
    std::unique_ptr<mmapped_vsifile> overviews_file_mapping;
};

#endif // GDAL_DATASOURCE_MMAP_HPP
<commit_msg>gdal: Virtual memory file needs to be registered under unique name<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2015 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
 *
 *****************************************************************************/

#ifndef GDAL_DATASOURCE_MMAP_HPP
#define GDAL_DATASOURCE_MMAP_HPP

#include <mapnik/util/fs.hpp>
#include <mapnik/make_unique.hpp>
#include <mapnik/debug.hpp>

#include <boost/interprocess/file_mapping.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <boost/filesystem.hpp>

#include <gdal_priv.h>

#include <sstream>

struct mmapped_vsifile
{
    mmapped_vsifile(std::string const& filepath,
                    std::string const& unique_path)
        : mapping(filepath.c_str(), boost::interprocess::read_only),
          region(mapping, boost::interprocess::read_only)
    {
        boost::filesystem::path vsimem_path("/vsimem");
        vsimem_path /= unique_path.empty() ? unique_id() : unique_path;
        vsimem_path /= filepath;

        virt_file = VSIFileFromMemBuffer(
            vsimem_path.string().c_str(),
            static_cast<GByte*>(region.get_address()),
            region.get_size(),
            false);

        if (virt_file == NULL)
        {
            throw std::runtime_error("Call to VSIFileFromMemBuffer "
                "failed with '" + vsimem_path.string() + "'");
        }

        name = vsimem_path.string();
    }

    std::string unique_id() const
    {
        std::stringstream ss;
        ss << region.get_address();
        return ss.str();
    }

    ~mmapped_vsifile()
    {
        VSIFCloseL(virt_file);
        VSIUnlink(name.c_str());
    }

    boost::interprocess::file_mapping mapping;
    boost::interprocess::mapped_region region;
    VSILFILE * virt_file;
    std::string name;
};

struct mmapped_tiff_dataset
{
    mmapped_tiff_dataset(std::string const& filepath)
        : tiff_file_mapping(filepath, std::string()),
          overviews_file_mapping()
    {
        std::string ovr_file_name = filepath + ".ovr";
        if (mapnik::util::exists(ovr_file_name))
        {
            try
            {
                overviews_file_mapping = std::make_unique<mmapped_vsifile>(
                    ovr_file_name, tiff_file_mapping.unique_id());
            }
            catch (std::exception const& e)
            {
                MAPNIK_LOG_ERROR(mmapped_tiff_dataset) <<
                    "gdal_datasource: Cannot mmap() "
                    " overviews file '" << ovr_file_name <<
                    "': " << e.what();
            }
        }
    }

    mmapped_vsifile tiff_file_mapping;
    std::unique_ptr<mmapped_vsifile> overviews_file_mapping;
};

#endif // GDAL_DATASOURCE_MMAP_HPP
<|endoftext|>


<commit_before>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <iosfwd>
#include <memory>
#include <string>

#include <windows.h>

#include "hadesmem/config.hpp"

namespace hadesmem
{

class Process;

class PeFile;

class Export
{
public:
  explicit Export(Process const& process, PeFile const& pe_file,
    WORD ordinal);

  Export(Export const& other);

  Export& operator=(Export const& other);

  Export(Export&& other) HADESMEM_NOEXCEPT;

  Export& operator=(Export&& other) HADESMEM_NOEXCEPT;

  ~Export();

  DWORD GetRva() const;

  PVOID GetVa() const;

  std::string GetName() const;

  WORD GetOrdinal() const;

  bool ByName() const;

  bool ByOrdinal() const;

  bool IsForwarded() const;

  std::string GetForwarder() const;

  std::string GetForwarderModule() const;

  std::string GetForwarderFunction() const;

  bool IsForwardedByOrdinal() const;

  WORD GetForwarderOrdinal() const;

private:
  struct Impl;
  std::unique_ptr<Impl> impl_;
};

bool operator==(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator!=(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator<(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator<=(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator>(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator>=(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

std::ostream& operator<<(std::ostream& lhs, Export const& rhs);

std::wostream& operator<<(std::wostream& lhs, Export const& rhs);

}
<commit_msg>* Note to self.<commit_after>// Copyright (C) 2010-2013 Joshua Boyce.
// See the file COPYING for copying permission.

#pragma once

#include <iosfwd>
#include <memory>
#include <string>

#include <windows.h>

#include "hadesmem/config.hpp"

namespace hadesmem
{

class Process;

class PeFile;

// TODO: Constructor to create Export by name (optimize using binary search).

class Export
{
public:
  explicit Export(Process const& process, PeFile const& pe_file,
    WORD ordinal);

  Export(Export const& other);

  Export& operator=(Export const& other);

  Export(Export&& other) HADESMEM_NOEXCEPT;

  Export& operator=(Export&& other) HADESMEM_NOEXCEPT;

  ~Export();

  DWORD GetRva() const;

  PVOID GetVa() const;

  std::string GetName() const;

  WORD GetOrdinal() const;

  bool ByName() const;

  bool ByOrdinal() const;

  bool IsForwarded() const;

  std::string GetForwarder() const;

  std::string GetForwarderModule() const;

  std::string GetForwarderFunction() const;

  bool IsForwardedByOrdinal() const;

  WORD GetForwarderOrdinal() const;

private:
  struct Impl;
  std::unique_ptr<Impl> impl_;
};

bool operator==(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator!=(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator<(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator<=(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator>(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

bool operator>=(Export const& lhs, Export const& rhs) HADESMEM_NOEXCEPT;

std::ostream& operator<<(std::ostream& lhs, Export const& rhs);

std::wostream& operator<<(std::wostream& lhs, Export const& rhs);

}
<|endoftext|>


<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

namespace MATH_NAMESPACE
{

//--------------------------------------------------------------------------------------------------
// plane3 members
//

template <size_t Dim, typename T, typename P>
MATH_FUNC
inline basic_plane<Dim, T, P>::basic_plane(vector<Dim, T> const& n, T o)
    : normal(n)
    , offset(o)
{
}

template <size_t Dim, typename T, typename P>
MATH_FUNC
inline basic_plane<Dim, T, P>::basic_plane(vector<Dim, T> const& n, vector<Dim, T> const& p)
    : normal(n)
    , offset(dot(n, p))
{
}

} // MATH_NAMESPACE
<commit_msg>Comparison operators for basic_plane<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

namespace MATH_NAMESPACE
{

//--------------------------------------------------------------------------------------------------
// plane3 members
//

template <size_t Dim, typename T, typename P>
MATH_FUNC
inline basic_plane<Dim, T, P>::basic_plane(vector<Dim, T> const& n, T o)
    : normal(n)
    , offset(o)
{
}

template <size_t Dim, typename T, typename P>
MATH_FUNC
inline basic_plane<Dim, T, P>::basic_plane(vector<Dim, T> const& n, vector<Dim, T> const& p)
    : normal(n)
    , offset(dot(n, p))
{
}

//--------------------------------------------------------------------------------------------------
// Comparisons
//

template <size_t Dim, typename T, typename P>
MATH_FUNC
inline bool operator==(basic_plane<Dim, T, P> const& a, basic_plane<Dim, T, P> const& b)
{
    return a.normal == b.normal && a.offset == b.offset;
}

template <size_t Dim, typename T, typename P>
MATH_FUNC
inline bool operator!=(basic_plane<Dim, T, P> const& a, basic_plane<Dim, T, P> const& b)
{
    return a.normal != b.normal || a.offset != b.offset;
}

} // MATH_NAMESPACE
<|endoftext|>


<commit_before>/*
network.cpp

misc network functions
*/
/*
Copyright  2009 Far Group
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. 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.
3. The name of the authors may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/

#include "headers.hpp"
#pragma hdrstop

#include "network.hpp"
#include "language.hpp"
#include "message.hpp"
#include "stddlg.hpp"
#include "drivemix.hpp"
#include "flink.hpp"
#include "cddrv.hpp"
#include "pathmix.hpp"

void GetStoredUserName(wchar_t cDrive, string &strUserName)
{
	//     WNetGetUser
	strUserName.clear();
	const wchar_t KeyName[]={L'N',L'e',L't',L'w',L'o',L'r',L'k',L'\\',cDrive,L'\0'};
	HKEY hKey;

	if (RegOpenKeyEx(HKEY_CURRENT_USER,KeyName,0,KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS && hKey)
	{
		RegQueryStringValue(hKey, L"UserName", strUserName);
		RegCloseKey(hKey);
	}
}

void AddSavedNetworkDisks(DWORD& Mask, DWORD& NetworkMask)
{
	HANDLE hEnum;

	if (!WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, 0, &hEnum))
	{
		DWORD bufsz = 16*1024;
		NETRESOURCE *netResource = (NETRESOURCE *)xf_malloc(bufsz);

		if (netResource)
		{
			while (1)
			{
				DWORD size=1;
				bufsz = 16*1024;
				memset(netResource,0,bufsz);
				DWORD res = WNetEnumResource(hEnum, &size, netResource, &bufsz);

				if (res == NO_ERROR && size > 0 && netResource->lpLocalName )
				{
					wchar_t letter = Lower(netResource->lpLocalName[0]);

					if (letter >= L'a' && letter <= L'z' && !wcscmp(netResource->lpLocalName+1, L":"))
					{
						int CurrBit = 1 << (letter - L'a');

						if (!(Mask&CurrBit))
						{
							Mask |= CurrBit;
							NetworkMask |=  CurrBit;
						}
					}
				}
				else
				{
					break;
				}
			}

			xf_free(netResource);
		}

		WNetCloseEnum(hEnum);
	}
}

void ConnectToNetworkDrive(const string& NewDir)
{
	string strRemoteName;
	DriveLocalToRemoteName(DRIVE_REMOTE_NOT_CONNECTED,NewDir[0],strRemoteName);
	string strUserName, strPassword;
	GetStoredUserName(NewDir[0], strUserName);
	NETRESOURCE netResource;
	netResource.dwType = RESOURCETYPE_DISK;
	netResource.lpLocalName = (wchar_t *)NewDir.data();
	netResource.lpRemoteName = (wchar_t *)strRemoteName.data();
	netResource.lpProvider = 0;
	DWORD res = WNetAddConnection2(&netResource, nullptr, EmptyToNull(strUserName.data()), 0);

	if (res == ERROR_SESSION_CREDENTIAL_CONFLICT)
		res = WNetAddConnection2(&netResource, nullptr, nullptr, 0);

	if (res)
	{
		while (1)
		{
			if (!GetNameAndPassword(strRemoteName, strUserName, strPassword, nullptr, GNP_USELAST))
				break;

			res = WNetAddConnection2(&netResource, strPassword.data(), EmptyToNull(strUserName.data()), 0);

			if (!res)
				break;

			if (res != ERROR_ACCESS_DENIED && res != ERROR_INVALID_PASSWORD && res != ERROR_LOGON_FAILURE)
			{
				Message(MSG_WARNING, 1, MSG(MError), GetErrorString().data(), MSG(MOk));
				break;
			}
		}
	}
}

string &CurPath2ComputerName(const string& CurDir, string &strComputerName)
{
	string strNetDir;
	strComputerName.clear();

	if (!CurDir.compare(0, 2, L"\\\\"))
	{
		strNetDir = CurDir;
	}
	else
	{
		string LocalName(CurDir.data(), 2);
		apiWNetGetConnection(LocalName, strNetDir);
	}

	if (!strNetDir.compare(0, 2, L"\\\\"))
	{
		strComputerName = strNetDir.data()+2;
		size_t pos;

		if (!FindSlash(pos,strComputerName))
			strComputerName.clear();
		else
			strComputerName.resize(pos);
	}

	return strComputerName;
}

bool DriveLocalToRemoteName(int DriveType, wchar_t Letter, string &strDest)
{
	bool NetPathShown=false, IsOK=false;
	wchar_t LocalName[8]=L" :\0\0\0";
	string strRemoteName;

	*LocalName=Letter;
	strDest.clear();

	if (DriveType == DRIVE_UNKNOWN)
	{
		LocalName[2]=L'\\';
		DriveType = FAR_GetDriveType(LocalName);
		LocalName[2]=0;
	}

	if (IsDriveTypeRemote(DriveType))
	{
		DWORD res = apiWNetGetConnection(LocalName,strRemoteName);

		if (res == NO_ERROR || res == ERROR_CONNECTION_UNAVAIL)
		{
			NetPathShown=true;
			IsOK=true;
		}
	}

	if (!NetPathShown && GetSubstName(DriveType, LocalName, strRemoteName))
		IsOK=true;

	if (IsOK)
		strDest = strRemoteName;

	return IsOK;
}
<commit_msg>one more lasterror<commit_after>/*
network.cpp

misc network functions
*/
/*
Copyright  2009 Far Group
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
2. 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.
3. The name of the authors may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/

#include "headers.hpp"
#pragma hdrstop

#include "network.hpp"
#include "language.hpp"
#include "message.hpp"
#include "stddlg.hpp"
#include "drivemix.hpp"
#include "flink.hpp"
#include "cddrv.hpp"
#include "pathmix.hpp"

void GetStoredUserName(wchar_t cDrive, string &strUserName)
{
	//     WNetGetUser
	strUserName.clear();
	const wchar_t KeyName[]={L'N',L'e',L't',L'w',L'o',L'r',L'k',L'\\',cDrive,L'\0'};
	HKEY hKey;

	if (RegOpenKeyEx(HKEY_CURRENT_USER,KeyName,0,KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS && hKey)
	{
		RegQueryStringValue(hKey, L"UserName", strUserName);
		RegCloseKey(hKey);
	}
}

void AddSavedNetworkDisks(DWORD& Mask, DWORD& NetworkMask)
{
	HANDLE hEnum;

	if (!WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, 0, &hEnum))
	{
		DWORD bufsz = 16*1024;
		NETRESOURCE *netResource = (NETRESOURCE *)xf_malloc(bufsz);

		if (netResource)
		{
			while (1)
			{
				DWORD size=1;
				bufsz = 16*1024;
				memset(netResource,0,bufsz);
				DWORD res = WNetEnumResource(hEnum, &size, netResource, &bufsz);

				if (res == NO_ERROR && size > 0 && netResource->lpLocalName )
				{
					wchar_t letter = Lower(netResource->lpLocalName[0]);

					if (letter >= L'a' && letter <= L'z' && !wcscmp(netResource->lpLocalName+1, L":"))
					{
						int CurrBit = 1 << (letter - L'a');

						if (!(Mask&CurrBit))
						{
							Mask |= CurrBit;
							NetworkMask |=  CurrBit;
						}
					}
				}
				else
				{
					break;
				}
			}

			xf_free(netResource);
		}

		WNetCloseEnum(hEnum);
	}
}

void ConnectToNetworkDrive(const string& NewDir)
{
	string strRemoteName;
	DriveLocalToRemoteName(DRIVE_REMOTE_NOT_CONNECTED,NewDir[0],strRemoteName);
	string strUserName, strPassword;
	GetStoredUserName(NewDir[0], strUserName);
	NETRESOURCE netResource;
	netResource.dwType = RESOURCETYPE_DISK;
	netResource.lpLocalName = (wchar_t *)NewDir.data();
	netResource.lpRemoteName = (wchar_t *)strRemoteName.data();
	netResource.lpProvider = 0;
	DWORD res = WNetAddConnection2(&netResource, nullptr, EmptyToNull(strUserName.data()), 0);

	if (res == ERROR_SESSION_CREDENTIAL_CONFLICT)
		res = WNetAddConnection2(&netResource, nullptr, nullptr, 0);

	if (res)
	{
		while (1)
		{
			if (!GetNameAndPassword(strRemoteName, strUserName, strPassword, nullptr, GNP_USELAST))
				break;

			res = WNetAddConnection2(&netResource, strPassword.data(), EmptyToNull(strUserName.data()), 0);

			if (!res)
				break;

			Global->CatchError();

			if (res != ERROR_ACCESS_DENIED && res != ERROR_INVALID_PASSWORD && res != ERROR_LOGON_FAILURE)
			{
				Message(MSG_WARNING, 1, MSG(MError), GetErrorString().data(), MSG(MOk));
				break;
			}
		}
	}
}

string &CurPath2ComputerName(const string& CurDir, string &strComputerName)
{
	string strNetDir;
	strComputerName.clear();

	if (!CurDir.compare(0, 2, L"\\\\"))
	{
		strNetDir = CurDir;
	}
	else
	{
		string LocalName(CurDir.data(), 2);
		apiWNetGetConnection(LocalName, strNetDir);
	}

	if (!strNetDir.compare(0, 2, L"\\\\"))
	{
		strComputerName = strNetDir.data()+2;
		size_t pos;

		if (!FindSlash(pos,strComputerName))
			strComputerName.clear();
		else
			strComputerName.resize(pos);
	}

	return strComputerName;
}

bool DriveLocalToRemoteName(int DriveType, wchar_t Letter, string &strDest)
{
	bool NetPathShown=false, IsOK=false;
	wchar_t LocalName[8]=L" :\0\0\0";
	string strRemoteName;

	*LocalName=Letter;
	strDest.clear();

	if (DriveType == DRIVE_UNKNOWN)
	{
		LocalName[2]=L'\\';
		DriveType = FAR_GetDriveType(LocalName);
		LocalName[2]=0;
	}

	if (IsDriveTypeRemote(DriveType))
	{
		DWORD res = apiWNetGetConnection(LocalName,strRemoteName);

		if (res == NO_ERROR || res == ERROR_CONNECTION_UNAVAIL)
		{
			NetPathShown=true;
			IsOK=true;
		}
	}

	if (!NetPathShown && GetSubstName(DriveType, LocalName, strRemoteName))
		IsOK=true;

	if (IsOK)
		strDest = strRemoteName;

	return IsOK;
}
<|endoftext|>


<commit_before>//============================================================================
// vSMC/include/vsmc/rng/normal_distribution.hpp
//----------------------------------------------------------------------------
//                         vSMC: Scalable Monte Carlo
//----------------------------------------------------------------------------
// Copyright (c) 2013-2015, Yan Zhou
// 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.
//
// 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 HOLDER 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.
//============================================================================

#ifndef VSMC_RNG_NORMAL_DISTRIBUTION_HPP
#define VSMC_RNG_NORMAL_DISTRIBUTION_HPP

#include <vsmc/rng/internal/common.hpp>
#include <vsmc/rng/u01_distribution.hpp>
#include <vsmc/rng/uniform_real_distribution.hpp>

#define VSMC_RUNTIME_ASSERT_RNG_NORMAL_DISTRIBUTION_PARAM_CHECK(stddev)       \
    VSMC_RUNTIME_ASSERT((stddev > 0), "**NormalDistribution** CONSTRUCTED "   \
                                      "WITH INVALID STANDARD DEVIATION "      \
                                      "PARAMETER VALUE")

namespace vsmc
{

namespace internal
{

template <typename RealType, typename RNGType>
inline void normal_distribution_impl(RNGType &rng, std::size_t n, RealType *r,
    RealType mean, RealType stddev, RealType *s)
{
    u01_distribution(rng, n, r);
    const std::size_t nu = n / 2;
    RealType *const u1 = r;
    RealType *const u2 = r + nu;
    math::vLn(nu, u1, s);
    math::vMul(nu, static_cast<RealType>(-2), s, s);
    math::vSqrt(nu, s, s);
    math::vMul(nu, math::pi_2<RealType>(), u2, u2);
    math::vSinCos(nu, u2, u1, u2);
    math::vMul(nu, stddev, s, s);
    math::vFMA(nu, mean, s, u1, u1);
    math::vFMA(nu, mean, s, u2, u2);
}

} // namespace vsmc::internal

/// \brief Generating normal random variates
/// \ingroup Distribution
template <typename RealType, typename RNGType>
inline void normal_distribution(RNGType &rng, std::size_t n, RealType *r,
    RealType mean = 0, RealType stddev = 1)
{
    const std::size_t k = 1000;
    const std::size_t m = n / k;
    const std::size_t l = n % k;
    RealType s[k / 2];
    for (std::size_t i = 0; i != m; ++i)
        internal::normal_distribution_impl(rng, k, r + i * k, mean, stddev, s);
    internal::normal_distribution_impl(rng, l, r + m * k, mean, stddev, s);
    if (n % 2 != 0) {
        U01DistributionType<RNGType, RealType> runif;
        RealType v1 = runif(rng);
        RealType v2 = runif(rng);
        r[n - 1] = mean +
            stddev * std::sqrt(-2 * std::log(v1)) *
                std::cos(math::pi_2<RealType>() * v2);
    }
}

/// \brief Normal distribution
/// \ingroup Distribution
template <typename RealType>
class NormalDistribution
{
    public:
    using result_type = RealType;
    using distribution_type = NormalDistribution<RealType>;

    class param_type
    {
        public:
        using result_type = RealType;
        using distribution_type = NormalDistribution<RealType>;

        explicit param_type(result_type mean = 0, result_type stddev = 1)
            : mean_(mean), stddev_(stddev), v_(0), saved_(false)
        {
            invariant();
        }

        result_type mean() const { return mean_; }
        result_type stddev() const { return stddev_; }

        friend bool operator==(
            const param_type &param1, const param_type &param2)
        {
            if (!internal::is_equal(param1.mean_, param2.mean_))
                return false;
            if (!internal::is_equal(param1.stddev_, param2.stddev_))
                return false;
            if (!internal::is_equal(param1.v_, param2.v_))
                return false;
            if (param1.saved_ && !param2.saved)
                return false;
            if (!param1.saved_ && param2.saved)
                return false;
            return true;
        }

        friend bool operator!=(
            const param_type &param1, const param_type &param2)
        {
            return !(param1 == param2);
        }

        template <typename CharT, typename Traits>
        friend std::basic_ostream<CharT, Traits> &operator<<(
            std::basic_ostream<CharT, Traits> &os, const param_type &param)
        {
            if (!os.good())
                return os;

            os << param.mean_ << ' ';
            os << param.stddev_ << ' ';
            os << param.v_ << ' ';
            os << param.saved_;

            return os;
        }

        template <typename CharT, typename Traits>
        friend std::basic_istream<CharT, Traits> &operator>>(
            std::basic_istream<CharT, Traits> &is, param_type &param)
        {
            if (!is.good())
                return is;

            result_type mean = 0;
            result_type stddev = 0;
            result_type v = 0;
            bool saved = false;
            is >> std::ws >> mean;
            is >> std::ws >> stddev;
            is >> std::ws >> v;
            is >> std::ws >> saved;

            if (is.good()) {
                if (stddev > 0) {
                    param = param_type(mean, stddev);
                    param.v_ = v;
                    param.saved_ = saved;
                } else {
                    is.setstate(std::ios_base::failbit);
                }
            }

            return is;
        }

        private:
        result_type mean_;
        result_type stddev_;
        result_type v_;
        bool saved_;

        friend distribution_type;

        void invariant()
        {
            VSMC_RUNTIME_ASSERT_RNG_NORMAL_DISTRIBUTION_PARAM_CHECK(stddev_);
            saved_ = false;
        }

        void reset() { saved_ = false; }
    }; // class param_type

    explicit NormalDistribution(result_type mean = 0, result_type stddev = 1)
        : param_(mean, stddev)
    {
    }

    explicit NormalDistribution(const param_type &param) : param_(param) {}

    result_type mean() const { return param_.mean_; }
    result_type stddev() const { return param_.stddev_; }

    result_type min VSMC_MNE() const
    {
        return -std::numeric_limits<result_type>::infinity();
    }

    result_type max VSMC_MNE() const
    {
        return std::numeric_limits<result_type>::infinity();
    }

    template <typename RNGType>
    result_type operator()(RNGType &rng)
    {
        if (param_.saved_) {
            param_.saved_ = false;
            return param_.v_;
        }

        result_type u = 0;
        result_type v = 0;
        generate_uv(rng, u, v, std::integral_constant<bool,
                                   internal::RNGBits<RNGType>::value >= 64>());
        result_type s = param_.stddev_ * std::sqrt(-2 * std::log(u));
        v = std::sin(math::pi_2<result_type>() * v);
        u = std::sqrt(1 - v * v);
        param_.v_ = param_.mean_ * v * s;
        param_.saved_ = true;

        return param_.mean_ + u * s;
    }

    VSMC_DEFINE_RNG_DISTRIBUTION_OPERATORS

    private:
    param_type param_;

    template <typename RNGType>
    void generate_uv(
        RNGType &rng, result_type &u, result_type &v, std::false_type)
    {
        U01DistributionType<RNGType, RealType> runif;
        u = 1 - runif(rng);
        v = 1 - runif(rng);
    }

    template <typename RNGType>
    void generate_uv(
        RNGType &rng, result_type &u, result_type &v, std::true_type)
    {
        std::uint64_t r = static_cast<std::uint64_t>(rng());
        u = U01<std::uint32_t, RealType, Open, Closed>::eval(r);
        v = U01<std::uint32_t, RealType, Open, Closed>::eval(r >> 32);
    }
}; // class NormalDistribution

} // namespace vsmc

#endif // VSMC_RNG_NORMAL_DISTRIBUTION_HPP
<commit_msg>make sure that the reuslts are finite<commit_after>//============================================================================
// vSMC/include/vsmc/rng/normal_distribution.hpp
//----------------------------------------------------------------------------
//                         vSMC: Scalable Monte Carlo
//----------------------------------------------------------------------------
// Copyright (c) 2013-2015, Yan Zhou
// 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.
//
// 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 HOLDER 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.
//============================================================================

#ifndef VSMC_RNG_NORMAL_DISTRIBUTION_HPP
#define VSMC_RNG_NORMAL_DISTRIBUTION_HPP

#include <vsmc/rng/internal/common.hpp>
#include <vsmc/rng/u01_distribution.hpp>
#include <vsmc/rng/uniform_real_distribution.hpp>

#define VSMC_RUNTIME_ASSERT_RNG_NORMAL_DISTRIBUTION_PARAM_CHECK(stddev)       \
    VSMC_RUNTIME_ASSERT((stddev > 0), "**NormalDistribution** CONSTRUCTED "   \
                                      "WITH INVALID STANDARD DEVIATION "      \
                                      "PARAMETER VALUE")

namespace vsmc
{

namespace internal
{

template <typename RealType, typename RNGType>
inline void normal_distribution_impl(RNGType &rng, std::size_t n, RealType *r,
    RealType mean, RealType stddev, RealType *s)
{
    const std::size_t nu = n / 2;
    RealType *const u1 = r;
    RealType *const u2 = r + nu;
    u01_distribution(rng, n, r);
    math::vSub(n, static_cast<RealType>(1), r, r);
    math::vLn(nu, u1, s);
    math::vMul(nu, static_cast<RealType>(-2), s, s);
    math::vSqrt(nu, s, s);
    math::vMul(nu, math::pi_2<RealType>(), u2, u2);
    math::vSinCos(nu, u2, u1, u2);
    math::vMul(nu, stddev, s, s);
    math::vFMA(nu, mean, s, u1, u1);
    math::vFMA(nu, mean, s, u2, u2);
}

} // namespace vsmc::internal

/// \brief Generating normal random variates
/// \ingroup Distribution
template <typename RealType, typename RNGType>
inline void normal_distribution(RNGType &rng, std::size_t n, RealType *r,
    RealType mean = 0, RealType stddev = 1)
{
    const std::size_t k = 1000;
    const std::size_t m = n / k;
    const std::size_t l = n % k;
    RealType s[k / 2];
    for (std::size_t i = 0; i != m; ++i)
        internal::normal_distribution_impl(rng, k, r + i * k, mean, stddev, s);
    internal::normal_distribution_impl(rng, l, r + m * k, mean, stddev, s);
    if (n % 2 != 0) {
        U01DistributionType<RNGType, RealType> runif;
        RealType v1 = runif(rng);
        RealType v2 = runif(rng);
        r[n - 1] = mean +
            stddev * std::sqrt(-2 * std::log(v1)) *
                std::cos(math::pi_2<RealType>() * v2);
    }
}

/// \brief Normal distribution
/// \ingroup Distribution
template <typename RealType>
class NormalDistribution
{
    public:
    using result_type = RealType;
    using distribution_type = NormalDistribution<RealType>;

    class param_type
    {
        public:
        using result_type = RealType;
        using distribution_type = NormalDistribution<RealType>;

        explicit param_type(result_type mean = 0, result_type stddev = 1)
            : mean_(mean), stddev_(stddev), v_(0), saved_(false)
        {
            invariant();
        }

        result_type mean() const { return mean_; }
        result_type stddev() const { return stddev_; }

        friend bool operator==(
            const param_type &param1, const param_type &param2)
        {
            if (!internal::is_equal(param1.mean_, param2.mean_))
                return false;
            if (!internal::is_equal(param1.stddev_, param2.stddev_))
                return false;
            if (!internal::is_equal(param1.v_, param2.v_))
                return false;
            if (param1.saved_ && !param2.saved)
                return false;
            if (!param1.saved_ && param2.saved)
                return false;
            return true;
        }

        friend bool operator!=(
            const param_type &param1, const param_type &param2)
        {
            return !(param1 == param2);
        }

        template <typename CharT, typename Traits>
        friend std::basic_ostream<CharT, Traits> &operator<<(
            std::basic_ostream<CharT, Traits> &os, const param_type &param)
        {
            if (!os.good())
                return os;

            os << param.mean_ << ' ';
            os << param.stddev_ << ' ';
            os << param.v_ << ' ';
            os << param.saved_;

            return os;
        }

        template <typename CharT, typename Traits>
        friend std::basic_istream<CharT, Traits> &operator>>(
            std::basic_istream<CharT, Traits> &is, param_type &param)
        {
            if (!is.good())
                return is;

            result_type mean = 0;
            result_type stddev = 0;
            result_type v = 0;
            bool saved = false;
            is >> std::ws >> mean;
            is >> std::ws >> stddev;
            is >> std::ws >> v;
            is >> std::ws >> saved;

            if (is.good()) {
                if (stddev > 0) {
                    param = param_type(mean, stddev);
                    param.v_ = v;
                    param.saved_ = saved;
                } else {
                    is.setstate(std::ios_base::failbit);
                }
            }

            return is;
        }

        private:
        result_type mean_;
        result_type stddev_;
        result_type v_;
        bool saved_;

        friend distribution_type;

        void invariant()
        {
            VSMC_RUNTIME_ASSERT_RNG_NORMAL_DISTRIBUTION_PARAM_CHECK(stddev_);
            saved_ = false;
        }

        void reset() { saved_ = false; }
    }; // class param_type

    explicit NormalDistribution(result_type mean = 0, result_type stddev = 1)
        : param_(mean, stddev)
    {
    }

    explicit NormalDistribution(const param_type &param) : param_(param) {}

    result_type mean() const { return param_.mean_; }
    result_type stddev() const { return param_.stddev_; }

    result_type min VSMC_MNE() const
    {
        return -std::numeric_limits<result_type>::infinity();
    }

    result_type max VSMC_MNE() const
    {
        return std::numeric_limits<result_type>::infinity();
    }

    template <typename RNGType>
    result_type operator()(RNGType &rng)
    {
        if (param_.saved_) {
            param_.saved_ = false;
            return param_.v_;
        }

        result_type u = 0;
        result_type v = 0;
        generate_uv(rng, u, v, std::integral_constant<bool,
                                   internal::RNGBits<RNGType>::value >= 64>());
        result_type s = param_.stddev_ * std::sqrt(-2 * std::log(u));
        v = std::sin(math::pi_2<result_type>() * v);
        u = std::sqrt(1 - v * v);
        param_.v_ = param_.mean_ * v * s;
        param_.saved_ = true;

        return param_.mean_ + u * s;
    }

    VSMC_DEFINE_RNG_DISTRIBUTION_OPERATORS

    private:
    param_type param_;

    template <typename RNGType>
    void generate_uv(
        RNGType &rng, result_type &u, result_type &v, std::false_type)
    {
        U01DistributionType<RNGType, RealType> runif;
        u = 1 - runif(rng);
        v = 1 - runif(rng);
    }

    template <typename RNGType>
    void generate_uv(
        RNGType &rng, result_type &u, result_type &v, std::true_type)
    {
        std::uint64_t r = static_cast<std::uint64_t>(rng());
        u = U01<std::uint32_t, RealType, Open, Closed>::eval(r);
        v = U01<std::uint32_t, RealType, Open, Closed>::eval(r >> 32);
    }
}; // class NormalDistribution

} // namespace vsmc

#endif // VSMC_RNG_NORMAL_DISTRIBUTION_HPP
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: b2dpolypolygoncutter.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: thb $ $Date: 2004-02-16 17:03:06 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX
#define _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _BGFX_POINT_B2DPOINT_HXX
#include <basegfx/point/b2dpoint.hxx>
#endif

#ifndef _BGFX_VECTOR_B2DVECTOR_HXX
#include <basegfx/vector/b2dvector.hxx>
#endif

#ifndef _BGFX_RANGE_B2DRANGE_HXX
#include <basegfx/range/b2drange.hxx>
#endif

#ifndef _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
#include <basegfx/polygon/b2dpolypolygon.hxx>
#endif

#include <vector>
#include <algorithm>

//////////////////////////////////////////////////////////////////////////////
// B2DPolygonNode class
//
// This class is a pure tooling class used to hold a polygon in double linked
// list form for faster manipulation. It is used from the polygon clipper.

namespace basegfx
{
    class B2DPolygonNode
    {
        ::basegfx::B2DPoint             maPosition;
        B2DPolygonNode*                         mpPrevious;
        B2DPolygonNode*                         mpNext;

        B2DPolygonNode*                         mpListPrevious;
        B2DPolygonNode*                         mpListNext;

    public:
        B2DPolygonNode(const ::basegfx::B2DPoint& rPosition, B2DPolygonNode* pPrevious);
        ~B2DPolygonNode();

        B2DPolygonNode* getPrevious() const { return mpPrevious; }
        B2DPolygonNode* getNext() const { return mpNext; }
        const ::basegfx::B2DPoint& getPosition() const { return maPosition; }

        void calcMinMaxX(double& fMaxAX, double& fMinAX) const;
        void calcMinMaxY(double& fMaxAY, double& fMinAY) const;

        void swapPreviousNext() { B2DPolygonNode* pZwi = mpPrevious; mpPrevious = mpNext; mpNext = pZwi; }
        void swapNextPointers(B2DPolygonNode* pCand);

        void addToList(B2DPolygonNode*& rpList);
        void remFromList(B2DPolygonNode*& rpList);

        bool getOrientation() const;
        void swapOrientation();
        ::basegfx::B2DRange getRange() const;

        // isInside tests for B2dPoint and other B2DPolygonNode Polygon. On border is not inside as long as
        // not true is given in bWithBorder flag.
        bool isInside(const ::basegfx::B2DPoint& rPnt, bool bWithBorder = false) const;
        bool isPolygonInside(B2DPolygonNode* pPoly, bool bWithBorder = false) const;
    };

    // a type definition to have a vector of pointers to B2DPolygonNodes
    typedef ::std::vector< B2DPolygonNode* > B2DPolygonNodeVector;

} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////
// B2DSimpleCut class

namespace basegfx
{
    class B2DSimpleCut
    {
        B2DPolygonNode*                         mpLeft;
        B2DPolygonNode*                         mpRight;

        // bitfield
        unsigned                                mbCorrectOrientation : 1;
        unsigned                                mbOrientation : 1;

    public:
        B2DSimpleCut(B2DPolygonNode* pL, B2DPolygonNode* pR, bool bCoOr = false, bool bOr = true)
        :   mpLeft(pL),
            mpRight(pR),
            mbCorrectOrientation(bCoOr),
            mbOrientation(bOr)
        {
        }

        void solve();
        B2DPolygonNode* getLeft() const { return mpLeft; }
        B2DPolygonNode* getRight() const { return mpRight; }

        bool isSameCut(B2DPolygonNode* pA, B2DPolygonNode* pB) const
        {
            return ((pA == mpLeft && pB == mpRight) || (pB == mpLeft && pA == mpRight));
        }
    };

    // a type definition to have a vector of pointers to B2DSimpleCuts
    typedef ::std::vector< B2DSimpleCut* > B2DSimpleCutVector;

} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////
// B2DClipExtraPolygonInfo class

namespace basegfx
{
    class B2DClipExtraPolygonInfo
    {
        ::basegfx::B2DRange             maRange;
        sal_Int32                               mnDepth;

        // bitfield
        unsigned                                mbOrientation : 1;

    public:
        B2DClipExtraPolygonInfo() {}

        void init(B2DPolygonNode* pNew);
        const ::basegfx::B2DRange& getRange() const { return maRange; }
        bool getOrientation() const { return mbOrientation; }

        sal_Int32 getDepth() const { return mnDepth; }
        void changeDepth(bool bOrientation);
    };
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////
// class B2DPolyPolygonCutter

namespace basegfx
{
    class B2DPolyPolygonCutter
    {
        // list of polys
        B2DPolygonNodeVector                    maPolygonList;
        B2DPolyPolygon                          maNotClosedPolygons;

        // help routines
        bool isSamePos(const ::basegfx::B2DPoint& rPntA, const ::basegfx::B2DPoint& rPntB)
        {
            return rPntA.equal(rPntB);
        }

        B2DSimpleCut* getExistingCut(B2DSimpleCutVector& rTmpCuts, B2DPolygonNode* pA, B2DPolygonNode* pB);
        B2DPolygonNode* extractNextPolygon(B2DPolygonNode*& rpList);
        bool isCrossover(B2DPolygonNode* pA, B2DPolygonNode* pB);
        bool isCrossover(B2DSimpleCut* pEnter, B2DSimpleCut* pLeave);

        bool isNextSamePos(B2DPolygonNode* pA, B2DPolygonNode* pB)
        {
            return isSamePos(pA->getNext()->getPosition(), pB->getNext()->getPosition());
        }

        bool isPrevSamePos(B2DPolygonNode* pA, B2DPolygonNode* pB)
        {
            return isSamePos(pA->getPrevious()->getPosition(), pB->getPrevious()->getPosition());
        }

        void addAllNodes(B2DPolygonNode* pPolygon, B2DPolygonNode*& rpList);
        B2DPolygonNode* createNewPolygon(const B2DPolygon& rPolygon);
        void deletePolygon(B2DPolygonNode* pCand);
        void polysToList(B2DPolygonNode*& rpList);
        void listToPolys(B2DPolygonNode*& rpList);

        bool doRangesIntersect(const ::basegfx::B2DRange& rRange1, const ::basegfx::B2DRange& rRange2) const
        {
            return rRange1.overlaps(rRange2);
        }

        bool doRangesInclude(const ::basegfx::B2DRange& rRange1, const ::basegfx::B2DRange& rRange2) const
        {
            return rRange1.isInside(rRange2);
        }

        void solveAllCuts(B2DSimpleCutVector& rCuts);

    public:
        B2DPolyPolygonCutter() {}
        ~B2DPolyPolygonCutter();

        // put/get poly
        void addPolyPolygon(const B2DPolyPolygon& rPolyPolygon, bool bForceOrientation = false);
        void getPolyPolygon(B2DPolyPolygon& rPolyPolygon);

        // transformations
        void removeSelfIntersections();
        void removeDoubleIntersections();

        // remove included
        void removeIncludedPolygons(bool bUseOr = true);
    };
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////

#endif /* _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX */
<commit_msg>INTEGRATION: CWS aw019 (1.5.36); FILE MERGED 2004/10/18 10:39:47 aw 1.5.36.1: #i34831#<commit_after>/*************************************************************************
 *
 *  $RCSfile: b2dpolypolygoncutter.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: pjunck $ $Date: 2004-11-03 08:34:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX
#define _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX

#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

#ifndef _BGFX_POINT_B2DPOINT_HXX
#include <basegfx/point/b2dpoint.hxx>
#endif

#ifndef _BGFX_RANGE_B2DRANGE_HXX
#include <basegfx/range/b2drange.hxx>
#endif

#ifndef _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
#include <basegfx/polygon/b2dpolypolygon.hxx>
#endif

#include <vector>

//////////////////////////////////////////////////////////////////////////////
// class B2DPolyPolygonCutter

namespace basegfx
{
    // predeclarations
    class B2DPolygonNode;
    class B2DSimpleCut;

    // a type definition to have a vector of pointers to B2DPolygonNodes
    typedef ::std::vector< B2DPolygonNode* > B2DPolygonNodeVector;

    // a type definition to have a vector of pointers to B2DSimpleCuts
    typedef ::std::vector< B2DSimpleCut* > B2DSimpleCutVector;

    class B2DPolyPolygonCutter
    {
        // list of polys
        B2DPolygonNodeVector                    maPolygonList;

        // help routines
        B2DSimpleCut* getExistingCut(B2DSimpleCutVector& rTmpCuts, B2DPolygonNode* pA, B2DPolygonNode* pB);
        B2DPolygonNode* extractNextPolygon(B2DPolygonNode*& rpList);
        bool isCrossover(B2DPolygonNode* pA, B2DPolygonNode* pB);
        bool isCrossover(B2DSimpleCut* pEnter, B2DSimpleCut* pLeave);
        bool isNextSamePos(B2DPolygonNode* pA, B2DPolygonNode* pB);
        bool isPrevSamePos(B2DPolygonNode* pA, B2DPolygonNode* pB);
        void addAllNodes(B2DPolygonNode* pPolygon, B2DPolygonNode*& rpList);
        B2DPolygonNode* createNewPolygon(const ::basegfx::B2DPolygon& rPolygon);
        void deletePolygon(B2DPolygonNode* pCand);
        void polysToList(B2DPolygonNode*& rpList);
        void listToPolys(B2DPolygonNode*& rpList);
        void solveAllCuts(B2DSimpleCutVector& rCuts);

    public:
        B2DPolyPolygonCutter() {}
        ~B2DPolyPolygonCutter();

        // put/get poly
        void addPolygon(const ::basegfx::B2DPolygon& rPolygon);
        void addPolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon);
        ::basegfx::B2DPolyPolygon getPolyPolygon();

        // transformations
        void removeSelfIntersections();
        void removeDoubleIntersections();
    };
} // end of namespace basegfx

//////////////////////////////////////////////////////////////////////////////

#endif /* _BGFX_POLYGON_B2DPOLYPOLYGONCUTTER_HXX */
<|endoftext|>


<commit_before>

/**
 * Copyright (c) 2017 blueback
 * Released under the MIT License
 * https://github.com/bluebackblue/brownie/blob/master/LICENSE
 * http://bbbproject.sakura.ne.jp/wordpress/mitlicense
 * @brief ＨＴＴＰ。
*/

/** include
*/
#include <bsys_pch.h>

/** include
*/
#include "../types/types.h"

/** include
*/
#include "./http.h"
#include "./http_recv.h"
#include "./http_send.h"
#include "./http_bodystring.h"
#include "./http_binaryitem.h"

/** NBsys::NHttp
*/
#if(BSYS_HTTP_ENABLE)
namespace NBsys{namespace NHttp
{
	/** constructor
	*/
	Http::Http()
		:
		host(""),
		port(80),
		mode(Http_Mode::Get),
		url(""),
		boundary_string(NHttp::MakeBoundaryString()),
		step(Step::None),
		socket(),
		iserror(false),
		send_buffer(),
		recv_buffer(),
		send(),
		recv(),
		binary_list()
	{
	}

	/** destructor
	*/
	Http::~Http()
	{
	}

	/** SetHost
	*/
	void Http::SetHost(const STLString& a_host)
	{
		this->host = a_host;
	}

	/** SetPort
	*/
	void Http::SetPort(s32 a_port)
	{
		this->port = a_port;
	}

	/** SetMode
	*/
	void Http::SetMode(Http_Mode::Id a_mode)
	{
		this->mode = a_mode;
	}

	/** SetUrl
	*/
	void Http::SetUrl(const STLString& a_url)
	{
		this->url = a_url;
	}

	/** SetBoundaryString
	*/
	void Http::SetBoundaryString(const STLString& a_boundary_string)
	{
		this->boundary_string = a_boundary_string;
	}

	/** コンテンツ追加。
	*/
	void Http::AddPostContent(const STLString& a_name,const STLString& a_filename,sharedptr< u8 >& a_data,s32 a_size)
	{
		//ヘッダー。
		STLString t_body_header = NHttp::MakeBodyString_BinaryHeader(this->boundary_string,a_name,a_filename);

		//フッター。
		STLString t_body_footer = NHttp::MakeBodyString_BinarFooter();

		//バッファ。
		s32 t_buffer_size = a_size + t_body_header.length() + t_body_footer.length();
		sharedptr<Http_BinaryItem> t_binary_item(new Http_BinaryItem());
		t_binary_item->data.reset(new u8[t_buffer_size + 1],default_delete<u8>());
		t_binary_item->data.get()[t_buffer_size] = 0x00;
		u8* t_buffer_data = t_binary_item->data.get();
		t_binary_item->size = t_buffer_size;

		//コピー。
		{
			s32 t_offset = 0;

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_header.c_str(),static_cast<s32>(t_body_header.length()));
			t_offset += static_cast<s32>(t_body_header.length());

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),a_data.get(),a_size);
			t_offset += static_cast<s32>(a_size);

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_footer.c_str(),static_cast<s32>(t_body_footer.length()));
			t_offset += static_cast<s32>(t_body_footer.length());

			ASSERT(t_offset == t_buffer_size);
		}

		this->binary_list.insert(STLMap<STLString,sharedptr<Http_BinaryItem>>::value_type(a_name,t_binary_item));
	}

	/** コンテンツ追加。
	*/
	void Http::AddPostContent(const STLString& a_name,const STLString& a_value)
	{
		//ヘッダー。
		STLString t_body_header = NHttp::MakeBodyString_TextHeader(this->boundary_string,a_name);

		//フッター。
		STLString t_body_footer = NHttp::MakeBodyString_TextFooter();

		//バッファ。
		s32 t_buffer_size = a_value.length() + t_body_header.length() + t_body_footer.length();
		sharedptr<Http_BinaryItem> t_binary_item(new Http_BinaryItem());
		t_binary_item->data.reset(new u8[t_buffer_size + 1],default_delete<u8>());
		t_binary_item->data.get()[t_buffer_size] = 0x00;
		u8* t_buffer_data = t_binary_item->data.get();
		t_binary_item->size = t_buffer_size;

		//コピー。
		{
			s32 t_offset = 0;

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_header.c_str(),static_cast<s32>(t_body_header.length()));
			t_offset += static_cast<s32>(t_body_header.length());

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),a_value.c_str(),a_value.length());
			t_offset += static_cast<s32>(a_value.length());

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_footer.c_str(),static_cast<s32>(t_body_footer.length()));
			t_offset += static_cast<s32>(t_body_footer.length());

			ASSERT(t_offset == t_buffer_size);
		}

		this->binary_list.insert(STLMap<STLString,sharedptr<Http_BinaryItem>>::value_type(a_name,t_binary_item));
	}

	/** IsRecvHeader
	*/
	bool Http::IsRecvHeader()
	{
		if(this->recv){
			return this->recv->IsRecvHeader();
		}

		return false;
	}

	/** IsRecvHeader
	*/
	s32 Http::GetStatusCode()
	{
		if(this->recv){
			return this->recv->GetStatusCode();
		}

		return -1;
	}

	/** GetContentLength
	*/
	s32 Http::GetContentLength()
	{
		if(this->recv){
			return this->recv->GetContentLength();
		}

		return -1;
	}

	/** 開始。
	*/
	void Http::ConnectStart(sharedptr<RingBufferBase<u8>>& a_recv_buffer)
	{
		this->recv_buffer = a_recv_buffer;
		this->step = Step::Start;
		this->iserror = false;

		//ソケット作成。
		this->socket.reset(new SocketHandle());

		//受信設定。
		this->recv.reset(new Http_Recv(this->socket,this->recv_buffer));

		//送信設定。
		this->send.reset(new Http_Send());
	}

	/** 終了。
	*/
	void Http::ConnectEnd()
	{
		this->step = Step::None;
		this->socket.reset();
		this->iserror = false;
		this->send_buffer.reset();
		this->recv_buffer.reset();
		this->send.reset();
		this->recv.reset();
	}

	/** 更新。
	*/
	bool Http::ConnectUpdate()
	{
		if(this->iserror == true){
			//中断。
			return false;
		}

		bool t_loop = true;
		while(t_loop){
			t_loop = false;

			if(this->send){
				if(this->send->Update() == true){
					//ループリクエスト。
					t_loop = true;
				}
				this->iserror = this->send->IsError();
			}
			if(this->recv){
				if(this->recv->Update() == true){
					//ループリクエスト。
					t_loop = true;
				}
			}

			switch(this->step){
			case Step::Start:
				{
					{
						s32 t_binary_size = 0;

						//バイナリ総サイズ。
						if(this->mode == Http_Mode::Post){
							for(STLMap<STLString,sharedptr<Http_BinaryItem>>::iterator t_it = this->binary_list.begin();t_it!=this->binary_list.end();t_it++){
								if(t_it->second != nullptr){
									t_binary_size += t_it->second->size;
								}
							}
						}

						//バイナリ終端文字列。
						STLString t_binary_footer = "";
						if(this->mode == Http_Mode::Post){
							NHttp::MakeBodyString_PostBinarFooter(this->boundary_string);
							t_binary_size += static_cast<s32>(t_binary_footer.length());
						}

						//ボディ作成。
						STLString t_send_body = NHttp::MakeBodyString_Header(this->boundary_string,this->mode,this->url,this->host,t_binary_size);

						//バッファ。
						s32 t_buffer_size = t_send_body.length() + t_binary_size;
						this->send_buffer.reset(new u8[t_buffer_size + 1],default_delete<u8>());
						this->send_buffer.get()[t_buffer_size] = 0x00;
						u8* t_buffer_data = this->send_buffer.get();

						//送信バッファの作成。
						{
							s32 t_offset = 0;

							//ボディー。
							Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_send_body.c_str(),static_cast<s32>(t_send_body.length()));
							t_offset += static_cast<s32>(t_send_body.length());

							if(this->mode == Http_Mode::Post){

								//バイナリ。
								for(STLMap<STLString,sharedptr<Http_BinaryItem>>::iterator t_it = this->binary_list.begin();t_it!=this->binary_list.end();t_it++){
									if(t_it->second != nullptr){
										Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_it->second->data.get(),t_it->second->size);
										t_offset += t_it->second->size;
									}
								}

								//バイナリ終端。
								Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_binary_footer.c_str(),static_cast<s32>(t_binary_footer.length()));
								t_offset += static_cast<s32>(t_binary_footer.length());
							}

							ASSERT(t_offset == t_buffer_size);
						}

						//送信バッファ設定。
						this->send->Send(this->socket,this->send_buffer,t_buffer_size);
					}

					this->step = Step::Connect;

					t_loop = true;
				}break;
			case Step::Connect:
				{
					//接続。

					if(this->socket->OpenTcp()){
						if(this->socket->ConnectTcp(this->host.c_str(),this->port) == true){
							this->step = Step::SendWait_StartData;
							t_loop = true;
						}else{
							//エラー。
							this->iserror = true;
						}
					}else{
						//エラー。
						this->iserror = true;
					}
				}break;
			case Step::SendWait_StartData:
				{
					if(this->send->IsBusy() == false){
						//受信開始。
						this->recv->StartRecv();
						this->step = Step::RecvHeader;
					}
				}break;
			case Step::RecvHeader:
				{
					//ヘッダー受信完了チェック。
					if(this->recv->IsRecvHeader()){
						this->step = Step::Recv;
					}
				}break;
			case Step::Recv:
				{
					bool t_close = false;
					if(this->recv->IsCopyContent()){
						//コンテンツの外部バッファへのコピー完了。
						t_close = true;
					}

					if(this->socket){
						if(this->socket->IsOpen() == false){
							t_close =  true;
						}
					}else{
						t_close = true;
					}

					if(t_close == true){
						if(this->socket){
							if(this->socket->IsOpen()){
								this->socket->Close();
							}
						}

						//正常終了 or 中断終了。
						return false;
					}
				}break;
			}
		}

		//継続。
		return true;
	}

}}
#endif

<commit_msg>bug fix<commit_after>

/**
 * Copyright (c) 2017 blueback
 * Released under the MIT License
 * https://github.com/bluebackblue/brownie/blob/master/LICENSE
 * http://bbbproject.sakura.ne.jp/wordpress/mitlicense
 * @brief ＨＴＴＰ。
*/

/** include
*/
#include <bsys_pch.h>

/** include
*/
#include "../types/types.h"

/** include
*/
#include "./http.h"
#include "./http_recv.h"
#include "./http_send.h"
#include "./http_bodystring.h"
#include "./http_binaryitem.h"

/** NBsys::NHttp
*/
#if(BSYS_HTTP_ENABLE)
namespace NBsys{namespace NHttp
{
	/** constructor
	*/
	Http::Http()
		:
		host(""),
		port(80),
		mode(Http_Mode::Get),
		url(""),
		boundary_string(NHttp::MakeBoundaryString()),
		step(Step::None),
		socket(),
		iserror(false),
		send_buffer(),
		recv_buffer(),
		send(),
		recv(),
		binary_list()
	{
	}

	/** destructor
	*/
	Http::~Http()
	{
	}

	/** SetHost
	*/
	void Http::SetHost(const STLString& a_host)
	{
		this->host = a_host;
	}

	/** SetPort
	*/
	void Http::SetPort(s32 a_port)
	{
		this->port = a_port;
	}

	/** SetMode
	*/
	void Http::SetMode(Http_Mode::Id a_mode)
	{
		this->mode = a_mode;
	}

	/** SetUrl
	*/
	void Http::SetUrl(const STLString& a_url)
	{
		this->url = a_url;
	}

	/** SetBoundaryString
	*/
	void Http::SetBoundaryString(const STLString& a_boundary_string)
	{
		this->boundary_string = a_boundary_string;
	}

	/** コンテンツ追加。
	*/
	void Http::AddPostContent(const STLString& a_name,const STLString& a_filename,sharedptr< u8 >& a_data,s32 a_size)
	{
		//ヘッダー。
		STLString t_body_header = NHttp::MakeBodyString_BinaryHeader(this->boundary_string,a_name,a_filename);

		//フッター。
		STLString t_body_footer = NHttp::MakeBodyString_BinarFooter();

		//バッファ。
		s32 t_buffer_size = static_cast<s32>(a_size + t_body_header.length() + t_body_footer.length());
		sharedptr<Http_BinaryItem> t_binary_item(new Http_BinaryItem());
		t_binary_item->data.reset(new u8[t_buffer_size + 1],default_delete<u8>());
		t_binary_item->data.get()[t_buffer_size] = 0x00;
		u8* t_buffer_data = t_binary_item->data.get();
		t_binary_item->size = t_buffer_size;

		//コピー。
		{
			s32 t_offset = 0;

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_header.c_str(),static_cast<s32>(t_body_header.length()));
			t_offset += static_cast<s32>(t_body_header.length());

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),a_data.get(),a_size);
			t_offset += static_cast<s32>(a_size);

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_footer.c_str(),static_cast<s32>(t_body_footer.length()));
			t_offset += static_cast<s32>(t_body_footer.length());

			ASSERT(t_offset == t_buffer_size);
		}

		this->binary_list.insert(STLMap<STLString,sharedptr<Http_BinaryItem>>::value_type(a_name,t_binary_item));
	}

	/** コンテンツ追加。
	*/
	void Http::AddPostContent(const STLString& a_name,const STLString& a_value)
	{
		//ヘッダー。
		STLString t_body_header = NHttp::MakeBodyString_TextHeader(this->boundary_string,a_name);

		//フッター。
		STLString t_body_footer = NHttp::MakeBodyString_TextFooter();

		//バッファ。
		s32 t_buffer_size = static_cast<s32>(a_value.length() + t_body_header.length() + t_body_footer.length());
		sharedptr<Http_BinaryItem> t_binary_item(new Http_BinaryItem());
		t_binary_item->data.reset(new u8[t_buffer_size + 1],default_delete<u8>());
		t_binary_item->data.get()[t_buffer_size] = 0x00;
		u8* t_buffer_data = t_binary_item->data.get();
		t_binary_item->size = t_buffer_size;

		//コピー。
		{
			s32 t_offset = 0;

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_header.c_str(),static_cast<s32>(t_body_header.length()));
			t_offset += static_cast<s32>(t_body_header.length());

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),a_value.c_str(),static_cast<s32>(a_value.length()));
			t_offset += static_cast<s32>(a_value.length());

			Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_body_footer.c_str(),static_cast<s32>(t_body_footer.length()));
			t_offset += static_cast<s32>(t_body_footer.length());

			ASSERT(t_offset == t_buffer_size);
		}

		this->binary_list.insert(STLMap<STLString,sharedptr<Http_BinaryItem>>::value_type(a_name,t_binary_item));
	}

	/** IsRecvHeader
	*/
	bool Http::IsRecvHeader()
	{
		if(this->recv){
			return this->recv->IsRecvHeader();
		}

		return false;
	}

	/** IsRecvHeader
	*/
	s32 Http::GetStatusCode()
	{
		if(this->recv){
			return this->recv->GetStatusCode();
		}

		return -1;
	}

	/** GetContentLength
	*/
	s32 Http::GetContentLength()
	{
		if(this->recv){
			return this->recv->GetContentLength();
		}

		return -1;
	}

	/** 開始。
	*/
	void Http::ConnectStart(sharedptr<RingBufferBase<u8>>& a_recv_buffer)
	{
		this->recv_buffer = a_recv_buffer;
		this->step = Step::Start;
		this->iserror = false;

		//ソケット作成。
		this->socket.reset(new SocketHandle());

		//受信設定。
		this->recv.reset(new Http_Recv(this->socket,this->recv_buffer));

		//送信設定。
		this->send.reset(new Http_Send());
	}

	/** 終了。
	*/
	void Http::ConnectEnd()
	{
		this->step = Step::None;
		this->socket.reset();
		this->iserror = false;
		this->send_buffer.reset();
		this->recv_buffer.reset();
		this->send.reset();
		this->recv.reset();
	}

	/** 更新。
	*/
	bool Http::ConnectUpdate()
	{
		if(this->iserror == true){
			//中断。
			return false;
		}

		bool t_loop = true;
		while(t_loop){
			t_loop = false;

			if(this->send){
				if(this->send->Update() == true){
					//ループリクエスト。
					t_loop = true;
				}
				this->iserror = this->send->IsError();
			}
			if(this->recv){
				if(this->recv->Update() == true){
					//ループリクエスト。
					t_loop = true;
				}
			}

			switch(this->step){
			case Step::Start:
				{
					{
						s32 t_binary_size = 0;

						//バイナリ総サイズ。
						if(this->mode == Http_Mode::Post){
							for(STLMap<STLString,sharedptr<Http_BinaryItem>>::iterator t_it = this->binary_list.begin();t_it!=this->binary_list.end();t_it++){
								if(t_it->second != nullptr){
									t_binary_size += t_it->second->size;
								}
							}
						}

						//バイナリ終端文字列。
						STLString t_binary_footer = "";
						if(this->mode == Http_Mode::Post){
							NHttp::MakeBodyString_PostBinarFooter(this->boundary_string);
							t_binary_size += static_cast<s32>(t_binary_footer.length());
						}

						//ボディ作成。
						STLString t_send_body = NHttp::MakeBodyString_Header(this->boundary_string,this->mode,this->url,this->host,t_binary_size);

						//バッファ。
						s32 t_buffer_size = static_cast<s32>(t_send_body.length() + t_binary_size);
						this->send_buffer.reset(new u8[t_buffer_size + 1],default_delete<u8>());
						this->send_buffer.get()[t_buffer_size] = 0x00;
						u8* t_buffer_data = this->send_buffer.get();

						//送信バッファの作成。
						{
							s32 t_offset = 0;

							//ボディー。
							Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_send_body.c_str(),static_cast<s32>(t_send_body.length()));
							t_offset += static_cast<s32>(t_send_body.length());

							if(this->mode == Http_Mode::Post){

								//バイナリ。
								for(STLMap<STLString,sharedptr<Http_BinaryItem>>::iterator t_it = this->binary_list.begin();t_it!=this->binary_list.end();t_it++){
									if(t_it->second != nullptr){
										Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_it->second->data.get(),t_it->second->size);
										t_offset += t_it->second->size;
									}
								}

								//バイナリ終端。
								Memory::Copy(&t_buffer_data[t_offset],(t_buffer_size - t_offset),t_binary_footer.c_str(),static_cast<s32>(t_binary_footer.length()));
								t_offset += static_cast<s32>(t_binary_footer.length());
							}

							ASSERT(t_offset == t_buffer_size);
						}

						//送信バッファ設定。
						this->send->Send(this->socket,this->send_buffer,t_buffer_size);
					}

					this->step = Step::Connect;

					t_loop = true;
				}break;
			case Step::Connect:
				{
					//接続。

					if(this->socket->OpenTcp()){
						if(this->socket->ConnectTcp(this->host.c_str(),this->port) == true){
							this->step = Step::SendWait_StartData;
							t_loop = true;
						}else{
							//エラー。
							this->iserror = true;
						}
					}else{
						//エラー。
						this->iserror = true;
					}
				}break;
			case Step::SendWait_StartData:
				{
					if(this->send->IsBusy() == false){
						//受信開始。
						this->recv->StartRecv();
						this->step = Step::RecvHeader;
					}
				}break;
			case Step::RecvHeader:
				{
					//ヘッダー受信完了チェック。
					if(this->recv->IsRecvHeader()){
						this->step = Step::Recv;
					}
				}break;
			case Step::Recv:
				{
					bool t_close = false;
					if(this->recv->IsCopyContent()){
						//コンテンツの外部バッファへのコピー完了。
						t_close = true;
					}

					if(this->socket){
						if(this->socket->IsOpen() == false){
							t_close =  true;
						}
					}else{
						t_close = true;
					}

					if(t_close == true){
						if(this->socket){
							if(this->socket->IsOpen()){
								this->socket->Close();
							}
						}

						//正常終了 or 中断終了。
						return false;
					}
				}break;
			}
		}

		//継続。
		return true;
	}

}}
#endif

<|endoftext|>