<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: respintest.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: vg $ $Date: 2007-03-26 14:08:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#undef UNICODE
#undef _UNICODE

#pragma warning(push, 1) /* disable warnings within system headers */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msiquery.h>
#pragma warning(pop)

#include <malloc.h>
#include <assert.h>

#include <tchar.h>
#include <string>
#include <systools/win32/uwinapi.h>

#if defined(_WIN32_WINNT) && !defined(__MINGW32__)
#error YES
#endif

using namespace std;

namespace
{
    string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
    {
        string  result;
        TCHAR   szDummy[1] = TEXT("");
        DWORD   nChars = 0;

        if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
        {
            DWORD nBytes = ++nChars * sizeof(TCHAR);
            LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
            ZeroMemory( buffer, nBytes );
            MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
            result = buffer;
        }
        return result;
    }

    inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
    {
        return (GetMsiProperty(handle, sProperty).length() > 0);
    }

    inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
    {
        MsiSetProperty(handle, sProperty.c_str(), NULL);
    }

    inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
    {
        MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
    }

} // namespace

extern "C" UINT __stdcall GetUserInstallMode(MSIHANDLE handle)
{
    string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));

    // MessageBox(NULL, sInstallPath.c_str(), "DEBUG", MB_OK);

    // unsetting all properties

    UnsetMsiProperty( handle, TEXT("INVALIDDIRECTORY") );
    UnsetMsiProperty( handle, TEXT("ISWRONGPRODUCT") );
    UnsetMsiProperty( handle, TEXT("PATCHISOLDER") );
    UnsetMsiProperty( handle, TEXT("ALLUSERS") );

    // 1. Searching for "ProductCode" in setup.ini

    string sSetupiniPath = sInstallPath + TEXT("program\\setup.ini");

    TCHAR szValue[32767];

    GetPrivateProfileString(
        TEXT("Bootstrap"),
        TEXT("ProductCode"),
        TEXT("INVALIDDIRECTORY"),
        szValue,
        elementsof(szValue),
        sSetupiniPath.c_str()
        );

    if ( !_tcsicmp( szValue, TEXT("INVALIDDIRECTORY") ) )
    {
        // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory.
        SetMsiProperty( handle, TEXT("INVALIDDIRECTORY"), TEXT("YES") );
        // MessageBox(NULL, "INVALIDDIRECTORY set", "DEBUG", MB_OK);
        return ERROR_SUCCESS;
    }

    // 2. Searching for "version.ini" and "bootstrap.ini"

    // version.ini is the new file, that shall be used. If there is no version.ini, it can be possible
    // that this is an old src680-version, in which only bootstrap.ini exists. In this case, the data
    // have to be read from bootstrap.ini.

    string sBootstrapPath = sInstallPath + TEXT("program\\bootstrap.ini");
    string sVersionPath = sInstallPath + TEXT("program\\version.ini");
    string sInfofilePath = "";
    string sectionname = "";

    WIN32_FIND_DATA data;
    HANDLE hdl = FindFirstFile(sVersionPath.c_str(), &data);

    // string mystr = "Searching for " + sVersionPath;
    // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);

    // if (hdl == INVALID_HANDLE_VALUE)
    if ( ! IsValidHandle(hdl) )
    {
        // version.ini not found.
        // Searching for bootstrap.ini

        hdl = FindFirstFile(sBootstrapPath.c_str(), &data);

        // mystr = "Searching for " + sBootstrapPath;
        // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);

        // if (hdl == INVALID_HANDLE_VALUE)
        if ( ! IsValidHandle(hdl) )
        {
            // Neither bootstrap.ini nor version.ini exist -> this is a wrong product
            // MessageBox(NULL, "Neither bootstrap.ini nor version.ini exist -> ISWRONGPRODUCT 1 set", "DEBUG", MB_OK);
            SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
            // MessageBox(NULL, "ISWRONGPRODUCT 1 set", "DEBUG", MB_OK);
            return ERROR_SUCCESS;
        }
        else
        {
            // bootstrap.ini found, it can be used as InfoFile
            sInfofilePath = sBootstrapPath;
            sectionname = TEXT("Bootstrap");
            // mystr = "bootstrap.ini found, section name: " + sectionname;
            // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);
        }
    }
    else
    {
        // version.ini found, it can be used as InfoFile
        sInfofilePath = sVersionPath;
        sectionname = TEXT("Version");
        // mystr = "version.ini found, section name: " + sectionname;
        // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);
    }

    // mystr = "Value of sInfofilePath: " + sInfofilePath;
    // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);

    // 3. Comparing first three characters of "PRODUCTMAJOR" from property table and "buildid" from InfoFile

    szValue[0] = '\0';

    GetPrivateProfileString(
        TEXT(sectionname.c_str()),
        TEXT("buildid"),
        TEXT("ISWRONGPRODUCT"),
        szValue,
        elementsof(szValue),
        sInfofilePath.c_str()
        );

    if ( !_tcsicmp( szValue, TEXT("ISWRONGPRODUCT") ) )
    {
        SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
        // MessageBox(NULL, "ISWRONGPRODUCT 1 set", "DEBUG", MB_OK);
        return ERROR_SUCCESS;
    }

    string ProductMajor = GetMsiProperty(handle, TEXT("PRODUCTMAJOR"));

    // Comparing the first three characters, for example "680"
    // If not equal, this version is not suited for patch or language pack

    if (_tcsnicmp(ProductMajor.c_str(), szValue, 3))
    {
        SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
        // MessageBox(NULL, "ISWRONGPRODUCT 2 set", "DEBUG", MB_OK);
        return ERROR_SUCCESS;
    }

    // 4. Only for patch: Comparing "PRODUCTMINOR from property table and "ProductMinor" from InfoFile

    string isPatch = GetMsiProperty(handle, TEXT("ISPATCH"));

    if (isPatch=="1")
    {
        string ProductMinor = GetMsiProperty(handle, TEXT("PRODUCTBUILDID"));
        int PatchProductMinor = atoi(ProductMinor.c_str());

        szValue[0] = '\0';

        GetPrivateProfileString(
            TEXT(sectionname.c_str()),
            TEXT("ProductBuildid"),
            TEXT("8918"),
            szValue,
            elementsof(szValue),
            sInfofilePath.c_str()
            );

        int InstalledProductMinor = atoi(szValue);

        if ( InstalledProductMinor >= PatchProductMinor )
        {
            SetMsiProperty( handle, TEXT("PATCHISOLDER"), TEXT("YES") );
            // MessageBox(NULL, "PATCHISOLDER set", "DEBUG", MB_OK);
            return ERROR_SUCCESS;
        }
    }

    // 5. Setting property ALLUSERS with value from "setup.ini"

    szValue[0] = '\0';

    GetPrivateProfileString(
        TEXT("Bootstrap"),
        TEXT("ALLUSERS"),
        TEXT(""),
        szValue,
        elementsof(szValue),
        sSetupiniPath.c_str()
        );

    if ( szValue[0] )
    {
        SetMsiProperty( handle, TEXT("ALLUSERS"), szValue );
        // MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK);
    }

    return ERROR_SUCCESS;
}
<commit_msg>INTEGRATION: CWS native82 (1.7.72); FILE MERGED 2007/03/29 11:54:38 is 1.7.72.4: RESYNC: (1.7-1.8); FILE MERGED 2007/03/28 07:26:34 dv 1.7.72.3: #i75394# Use only one function definition of SetMSIErrorCode 2007/03/27 11:53:37 dv 1.7.72.2: #i75394# Use the name global... for the memory mapped file 2007/03/27 11:51:53 dv 1.7.72.1: #i75394# Transfer error codes to setup loader<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: respintest.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: gm $ $Date: 2007-05-10 11:02:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#undef UNICODE
#undef _UNICODE

#pragma warning(push, 1) /* disable warnings within system headers */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <msiquery.h>
#pragma warning(pop)

#include <malloc.h>
#include <assert.h>

#include <tchar.h>
#include <string>
#include <systools/win32/uwinapi.h>

#include <../tools/seterror.hxx>

#if defined(_WIN32_WINNT) && !defined(__MINGW32__)
#error YES
#endif

using namespace std;

namespace
{
    string GetMsiProperty(MSIHANDLE handle, const string& sProperty)
    {
        string  result;
        TCHAR   szDummy[1] = TEXT("");
        DWORD   nChars = 0;

        if (MsiGetProperty(handle, sProperty.c_str(), szDummy, &nChars) == ERROR_MORE_DATA)
        {
            DWORD nBytes = ++nChars * sizeof(TCHAR);
            LPTSTR buffer = reinterpret_cast<LPTSTR>(_alloca(nBytes));
            ZeroMemory( buffer, nBytes );
            MsiGetProperty(handle, sProperty.c_str(), buffer, &nChars);
            result = buffer;
        }
        return result;
    }

    inline bool IsSetMsiProperty(MSIHANDLE handle, const string& sProperty)
    {
        return (GetMsiProperty(handle, sProperty).length() > 0);
    }

    inline void UnsetMsiProperty(MSIHANDLE handle, const string& sProperty)
    {
        MsiSetProperty(handle, sProperty.c_str(), NULL);
    }

    inline void SetMsiProperty(MSIHANDLE handle, const string& sProperty, const string&)
    {
        MsiSetProperty(handle, sProperty.c_str(), TEXT("1"));
    }
} // namespace

extern "C" UINT __stdcall GetUserInstallMode(MSIHANDLE handle)
{
    string sInstallPath = GetMsiProperty(handle, TEXT("INSTALLLOCATION"));

    // MessageBox(NULL, sInstallPath.c_str(), "DEBUG", MB_OK);

    // unsetting all properties

    UnsetMsiProperty( handle, TEXT("INVALIDDIRECTORY") );
    UnsetMsiProperty( handle, TEXT("ISWRONGPRODUCT") );
    UnsetMsiProperty( handle, TEXT("PATCHISOLDER") );
    UnsetMsiProperty( handle, TEXT("ALLUSERS") );

    // 1. Searching for "ProductCode" in setup.ini

    string sSetupiniPath = sInstallPath + TEXT("program\\setup.ini");

    TCHAR szValue[32767];

    GetPrivateProfileString(
        TEXT("Bootstrap"),
        TEXT("ProductCode"),
        TEXT("INVALIDDIRECTORY"),
        szValue,
        elementsof(szValue),
        sSetupiniPath.c_str()
        );

    if ( !_tcsicmp( szValue, TEXT("INVALIDDIRECTORY") ) )
    {
        // No setup.ini or no "ProductCode" in setup.ini. This is an invalid directory.
        SetMsiProperty( handle, TEXT("INVALIDDIRECTORY"), TEXT("YES") );
        // MessageBox(NULL, "INVALIDDIRECTORY set", "DEBUG", MB_OK);
        SetMsiErrorCode( MSI_ERROR_INVALIDDIRECTORY );
        return ERROR_SUCCESS;
    }

    // 2. Searching for "version.ini" and "bootstrap.ini"

    // version.ini is the new file, that shall be used. If there is no version.ini, it can be possible
    // that this is an old src680-version, in which only bootstrap.ini exists. In this case, the data
    // have to be read from bootstrap.ini.

    string sBootstrapPath = sInstallPath + TEXT("program\\bootstrap.ini");
    string sVersionPath = sInstallPath + TEXT("program\\version.ini");
    string sInfofilePath = "";
    string sectionname = "";

    WIN32_FIND_DATA data;
    HANDLE hdl = FindFirstFile(sVersionPath.c_str(), &data);

    // string mystr = "Searching for " + sVersionPath;
    // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);

    // if (hdl == INVALID_HANDLE_VALUE)
    if ( ! IsValidHandle(hdl) )
    {
        // version.ini not found.
        // Searching for bootstrap.ini

        hdl = FindFirstFile(sBootstrapPath.c_str(), &data);

        // mystr = "Searching for " + sBootstrapPath;
        // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);

        // if (hdl == INVALID_HANDLE_VALUE)
        if ( ! IsValidHandle(hdl) )
        {
            // Neither bootstrap.ini nor version.ini exist -> this is a wrong product
            // MessageBox(NULL, "Neither bootstrap.ini nor version.ini exist -> ISWRONGPRODUCT 1 set", "DEBUG", MB_OK);
            SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
            // MessageBox(NULL, "ISWRONGPRODUCT 1 set", "DEBUG", MB_OK);
            SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
            return ERROR_SUCCESS;
        }
        else
        {
            // bootstrap.ini found, it can be used as InfoFile
            sInfofilePath = sBootstrapPath;
            sectionname = TEXT("Bootstrap");
            // mystr = "bootstrap.ini found, section name: " + sectionname;
            // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);
        }
    }
    else
    {
        // version.ini found, it can be used as InfoFile
        sInfofilePath = sVersionPath;
        sectionname = TEXT("Version");
        // mystr = "version.ini found, section name: " + sectionname;
        // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);
    }

    // mystr = "Value of sInfofilePath: " + sInfofilePath;
    // MessageBox(NULL, mystr.c_str(), "DEBUG", MB_OK);

    // 3. Comparing first three characters of "PRODUCTMAJOR" from property table and "buildid" from InfoFile

    szValue[0] = '\0';

    GetPrivateProfileString(
        TEXT(sectionname.c_str()),
        TEXT("buildid"),
        TEXT("ISWRONGPRODUCT"),
        szValue,
        elementsof(szValue),
        sInfofilePath.c_str()
        );

    if ( !_tcsicmp( szValue, TEXT("ISWRONGPRODUCT") ) )
    {
        SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
        // MessageBox(NULL, "ISWRONGPRODUCT 1 set", "DEBUG", MB_OK);
        SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
        return ERROR_SUCCESS;
    }

    string ProductMajor = GetMsiProperty(handle, TEXT("PRODUCTMAJOR"));

    // Comparing the first three characters, for example "680"
    // If not equal, this version is not suited for patch or language pack

    if (_tcsnicmp(ProductMajor.c_str(), szValue, 3))
    {
        SetMsiProperty( handle, TEXT("ISWRONGPRODUCT"), TEXT("YES") );
        // MessageBox(NULL, "ISWRONGPRODUCT 2 set", "DEBUG", MB_OK);
        SetMsiErrorCode( MSI_ERROR_ISWRONGPRODUCT );
        return ERROR_SUCCESS;
    }

    // 4. Only for patch: Comparing "PRODUCTMINOR from property table and "ProductMinor" from InfoFile

    string isPatch = GetMsiProperty(handle, TEXT("ISPATCH"));

    if (isPatch=="1")
    {
        string ProductMinor = GetMsiProperty(handle, TEXT("PRODUCTBUILDID"));
        int PatchProductMinor = atoi(ProductMinor.c_str());

        szValue[0] = '\0';

        GetPrivateProfileString(
            TEXT(sectionname.c_str()),
            TEXT("ProductBuildid"),
            TEXT("8918"),
            szValue,
            elementsof(szValue),
            sInfofilePath.c_str()
            );

        int InstalledProductMinor = atoi(szValue);

        if ( InstalledProductMinor >= PatchProductMinor )
        {
            SetMsiProperty( handle, TEXT("PATCHISOLDER"), TEXT("YES") );
            // MessageBox(NULL, "PATCHISOLDER set", "DEBUG", MB_OK);
            SetMsiErrorCode( MSI_ERROR_PATCHISOLDER );
            return ERROR_SUCCESS;
        }
    }

    // 5. Setting property ALLUSERS with value from "setup.ini"

    szValue[0] = '\0';

    GetPrivateProfileString(
        TEXT("Bootstrap"),
        TEXT("ALLUSERS"),
        TEXT(""),
        szValue,
        elementsof(szValue),
        sSetupiniPath.c_str()
        );

    if ( szValue[0] )
    {
        SetMsiProperty( handle, TEXT("ALLUSERS"), szValue );
        // MessageBox(NULL, "ALLUSERS set", "DEBUG", MB_OK);
    }

    return ERROR_SUCCESS;
}
<|endoftext|>


<commit_before>#include "libtorrent/session.hpp"
#include "libtorrent/alert_types.hpp"

#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <memory>
#include <mutex>
#include <stdlib.h>

using namespace libtorrent;

void usage()
{
	std::cerr << "USAGE: bootstrap-dht-bot <host> <port>" << std::endl;
	exit(1);
}

void dispatch_libtorrent_alert(std::shared_ptr<session> s, std::auto_ptr<libtorrent::alert> libtorrent_alert)
{
    std::cerr << "libtorrent alert: " << libtorrent_alert->message() << std::endl;
    switch (libtorrent_alert->type()) {
        case libtorrent::dht_bootstrap_alert::alert_type:
            std::cerr << "bootstrapping successful" << std::endl;
            break;
    }
}

int main(int argc, char* argv[])
{
	if (argc != 3) {
        usage();
    }

    const char* host = argv[1];
    int port = atoi(argv[2]);
    int flags = 0;

    if (port == 0) {
        std::cerr << "error: port is invalid" << std::endl;
        exit(-1);
    }

    libtorrent::fingerprint fp("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0);
    std::shared_ptr<libtorrent::session> s = std::make_shared<libtorrent::session>(
            fp, std::make_pair(port, port + 8), "0.0.0.0", flags,
            libtorrent::alert::port_mapping_notification |
            libtorrent::alert::debug_notification |
            libtorrent::alert::dht_notification |
            libtorrent::alert::error_notification |
            libtorrent::alert::status_notification);

    s->set_alert_dispatch(std::bind(&dispatch_libtorrent_alert, s, std::placeholders::_1));
    s->add_dht_router(std::make_pair(host, 6881));
    s->start_dht();

    // Just block here and let the session run forever.
    std::mutex forever;
    forever.lock();
    forever.lock();
}
<commit_msg>Update bot to take in a session port<commit_after>#include "libtorrent/session.hpp"
#include "libtorrent/alert_types.hpp"

#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <memory>
#include <mutex>
#include <stdlib.h>

using namespace libtorrent;

void usage()
{
	std::cerr << "USAGE: bootstrap-dht-bot <server-host> <server-port> <session-port>" << std::endl;
	exit(1);
}

void dispatch_libtorrent_alert(std::shared_ptr<session> s, std::auto_ptr<libtorrent::alert> libtorrent_alert)
{
    std::cerr << "libtorrent alert: " << libtorrent_alert->message() << std::endl;
    switch (libtorrent_alert->type()) {
        case libtorrent::dht_bootstrap_alert::alert_type:
            std::cerr << "bootstrapping successful" << std::endl;
            break;
    }
}

int main(int argc, char* argv[])
{
    if (argc != 4) {
        usage();
    }

    const char* server_host = argv[1];
    int server_port = atoi(argv[2]);
    int session_port = atoi(argv[3]);
    int flags = 0;

    if (server_port == 0) {
        std::cerr << "error: server port '" << server_port << "' is invalid" << std::endl;
        exit(-1);
    }

    if (session_port == 0) {
        std::cerr << "error: session port '" << session_port << "' is invalid" << std::endl;
        exit(-1);
    }

    libtorrent::fingerprint fp("LT", LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR, 0, 0);
    std::shared_ptr<libtorrent::session> session = std::make_shared<libtorrent::session>(
            fp, std::make_pair(session_port, session_port + 8), "0.0.0.0", flags,
            libtorrent::alert::port_mapping_notification |
            libtorrent::alert::debug_notification |
            libtorrent::alert::dht_notification |
            libtorrent::alert::error_notification |
            libtorrent::alert::status_notification);

    session->set_alert_dispatch(std::bind(&dispatch_libtorrent_alert, session, std::placeholders::_1));
    session->add_dht_router(std::make_pair(server_host, server_port));
    session->start_dht();

    // Just block here and let the session run forever.
    std::mutex forever;
    forever.lock();
    forever.lock();

    std::cerr << "stopping bot" << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>d391ceeb-4b02-11e5-9030-28cfe9171a43<commit_msg>#BUG723 uncommitted code found on my computer Monday morning<commit_after>d39d06c0-4b02-11e5-8936-28cfe9171a43<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"

#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>
#include "named_type.hpp"

// Usage examples

template<typename T>
decltype(auto) tee(T&& value)
{
    std::cout << value << '\n';
    return std::forward<T>(value);
}

using Meter = fluent::NamedType<double, struct MeterParameter, fluent::Addable, fluent::Comparable>;
Meter operator"" _meter(unsigned long long value) { return Meter(value); }
//Meter operator"" _meter(long double value) { return Meter(value); }

using Width = fluent::NamedType<Meter, struct WidthParameter>;
using Height = fluent::NamedType<Meter, struct HeightParameter>;

class Rectangle
{
public:
    Rectangle(Width width, Height height) : width_(width.get()), height_(height.get()) {}
    Meter getWidth() const { return width_; }
    Meter getHeight() const { return height_; }

private:
    Meter width_;
    Meter height_;
};

TEST_CASE("Basic usage")
{
    Rectangle r(Width(10_meter), Height(12_meter));
    REQUIRE(r.getWidth().get() == 10);
    REQUIRE(r.getHeight().get() == 12);
}

using NameRef = fluent::NamedType<std::string&, struct NameRefParameter>;

void changeValue(NameRef name)
{
    name.get() = "value2";
}

TEST_CASE("Passing a strong reference")
{
    std::string value = "value1";
    changeValue(NameRef(value));
    REQUIRE(value == "value2");
}

TEST_CASE("Construction of NamedType::ref from the underlying type")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    int i = 42;
    addOne(StrongInt::ref(i));
    REQUIRE(i == 43);
}

TEST_CASE("Implicit conversion of NamedType to NamedType::ref")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    StrongInt i(42);
    addOne(i);
    REQUIRE(i.get() == 43);

    StrongInt j(42);
    addOne(StrongInt::ref(j));
    REQUIRE(j.get() == 43);
}

template<typename Function>
using Comparator = fluent::NamedType<Function, struct ComparatorParameter>;

template <typename Function>
std::string performAction(Comparator<Function> comp)
{
    return comp.get()();
}

TEST_CASE("Strong generic type")
{
    REQUIRE(performAction(fluent::make_named<Comparator>([](){ return std::string("compare"); })) == "compare");
}

TEST_CASE("Addable")
{
    using AddableType = fluent::NamedType<int, struct AddableTag, fluent::Addable>;
    AddableType s1(12);
    AddableType s2(10);
    REQUIRE((s1 + s2).get() == 22);
    REQUIRE((+s1).get() == 12);
}

TEST_CASE("BinaryAddable")
{
    using BinaryAddableType = fluent::NamedType<int, struct BinaryAddableTag, fluent::BinaryAddable>;
    BinaryAddableType s1(12);
    BinaryAddableType s2(10);
    REQUIRE((s1 + s2).get() == 22);
}

TEST_CASE("UnaryAddable")
{
    using UnaryAddableType = fluent::NamedType<int, struct UnaryAddableTag, fluent::UnaryAddable>;
    UnaryAddableType s1(12);
    REQUIRE((+s1).get() == 12);
}

TEST_CASE("Subtractable")
{
    using SubtractableType = fluent::NamedType<int, struct SubtractableTag, fluent::Subtractable>;
    SubtractableType s1(12);
    SubtractableType s2(10);
    REQUIRE((s1 - s2).get() == 2);
    REQUIRE((-s1).get() == -12);
}

TEST_CASE("BinarySubtractable")
{
    using BinarySubtractableType = fluent::NamedType<int, struct BinarySubtractableTag, fluent::BinarySubtractable>;
    BinarySubtractableType s1(12);
    BinarySubtractableType s2(10);
    REQUIRE((s1 - s2).get() == 2);
}

TEST_CASE("UnarySubtractable")
{
    using UnarySubtractableType = fluent::NamedType<int, struct UnarySubtractableTag, fluent::UnarySubtractable>;
    UnarySubtractableType s(12);
    REQUIRE((-s).get() == -12);
}

TEST_CASE("Multiplicable")
{
    using MultiplicableType = fluent::NamedType<int, struct MultiplicableTag, fluent::Multiplicable>;
    MultiplicableType s1(12);
    MultiplicableType s2(10);
    REQUIRE((s1 * s2).get() == 120);
}

TEST_CASE("Negatable")
{
  using NegatableType = fluent::NamedType<int, struct NegatableTag, fluent::Negatable>;
  NegatableType value(10);
  REQUIRE((-value).get() == -10);
}

TEST_CASE("Comparable")
{
    REQUIRE((10_meter == 10_meter));
    REQUIRE(!(10_meter == 11_meter));
    REQUIRE((10_meter != 11_meter));
    REQUIRE(!(10_meter != 10_meter));
    REQUIRE((10_meter <  11_meter));
    REQUIRE(!(10_meter <  10_meter));
    REQUIRE((10_meter <= 10_meter));
    REQUIRE((10_meter <= 11_meter));
    REQUIRE(!(10_meter <= 9_meter));
    REQUIRE((11_meter >  10_meter));
    REQUIRE(!(10_meter > 11_meter));
    REQUIRE((11_meter >= 10_meter));
    REQUIRE((10_meter >= 10_meter));
    REQUIRE(!(9_meter >= 10_meter));
}

TEST_CASE("ConvertibleWithOperator")
{
    struct B
    {
        B(int x) : x(x) {}
        int x;
    };

    struct A
    {
        A(int x) : x(x) {}
        operator B () const { return B(x);}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleWithConstructor")
{
    struct A
    {
        A(int x) : x(x) {}
        int x;
    };

    struct B
    {
        B(A a) : x(a.x) {}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleToItself")
{
    using MyInt = fluent::NamedType<int, struct MyIntTag, fluent::ImplicitlyConvertibleTo<int>::templ>;
    MyInt myInt(42);
    int i = myInt;
    REQUIRE(i == 42);
}

TEST_CASE("Hash")
{
    using SerialNumber = fluent::NamedType<std::string, struct SerialNumberTag, fluent::Comparable, fluent::Hashable>;

    std::unordered_map<SerialNumber, int> hashMap = { {SerialNumber{"AA11"}, 10}, {SerialNumber{"BB22"}, 20} };
    SerialNumber cc33{"CC33"};
    hashMap[cc33] = 30;
    REQUIRE(hashMap[SerialNumber{"AA11"}] == 10);
    REQUIRE(hashMap[SerialNumber{"BB22"}] == 20);
    REQUIRE(hashMap[cc33] == 30);
}

struct testFunctionCallable_A
{
    testFunctionCallable_A(int x) : x(x) {}
    testFunctionCallable_A(testFunctionCallable_A const&) = delete; // ensures that passing the argument to a function doesn't make a copy
    testFunctionCallable_A(testFunctionCallable_A&&) = default;
    testFunctionCallable_A& operator+=(testFunctionCallable_A const& other) { x += other.x; return *this; }
    int x;
};

testFunctionCallable_A operator+(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return testFunctionCallable_A(a1.x + a2.x);
}

bool operator==(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return a1.x == a2.x;
}

TEST_CASE("Function callable")
{
    using A = testFunctionCallable_A;
    auto functionTakingA = [](A const& a){ return a.x; };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::FunctionCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A(42));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(functionTakingA(constStrongA) == 42);
    REQUIRE(strongA + strongA == 84);
}

TEST_CASE("Method callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::MethodCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method or function doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    auto functionTakingA = [](A const& a){ return a.constMethod(); };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::Callable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Named arguments")
{
    using FirstName = fluent::NamedType<std::string, struct FirstNameTag>;
    using LastName = fluent::NamedType<std::string, struct LastNameTag>;
    static const FirstName::argument firstName;
    static const LastName::argument lastName;
    auto getFullName = [](FirstName const& firstName, LastName const& lastName)
    {
        return firstName.get() + lastName.get();
    };

    auto fullName = getFullName(firstName = "James", lastName = "Bond");
    REQUIRE(fullName == "JamesBond");
}

TEST_CASE("Named arguments with bracket constructor")
{
    using Numbers = fluent::NamedType<std::vector<int>, struct NumbersTag>;
    static const Numbers::argument numbers;
    auto getNumbers = [](Numbers const& numbers)
    {
        return numbers.get();
    };

    auto vec = getNumbers(numbers = {1, 2, 3});
    REQUIRE(vec == std::vector<int>{1, 2, 3});
}

TEST_CASE("Empty base class optimization")
{
    REQUIRE(sizeof(Meter) == sizeof(double));
}
<commit_msg>Add test for default construction<commit_after>#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"

#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>
#include "named_type.hpp"

// Usage examples

template<typename T>
decltype(auto) tee(T&& value)
{
    std::cout << value << '\n';
    return std::forward<T>(value);
}

using Meter = fluent::NamedType<double, struct MeterParameter, fluent::Addable, fluent::Comparable>;
Meter operator"" _meter(unsigned long long value) { return Meter(value); }
//Meter operator"" _meter(long double value) { return Meter(value); }

using Width = fluent::NamedType<Meter, struct WidthParameter>;
using Height = fluent::NamedType<Meter, struct HeightParameter>;

class Rectangle
{
public:
    Rectangle(Width width, Height height) : width_(width.get()), height_(height.get()) {}
    Meter getWidth() const { return width_; }
    Meter getHeight() const { return height_; }

private:
    Meter width_;
    Meter height_;
};

TEST_CASE("Basic usage")
{
    Rectangle r(Width(10_meter), Height(12_meter));
    REQUIRE(r.getWidth().get() == 10);
    REQUIRE(r.getHeight().get() == 12);
}

using NameRef = fluent::NamedType<std::string&, struct NameRefParameter>;

void changeValue(NameRef name)
{
    name.get() = "value2";
}

TEST_CASE("Passing a strong reference")
{
    std::string value = "value1";
    changeValue(NameRef(value));
    REQUIRE(value == "value2");
}

TEST_CASE("Construction of NamedType::ref from the underlying type")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    int i = 42;
    addOne(StrongInt::ref(i));
    REQUIRE(i == 43);
}

TEST_CASE("Implicit conversion of NamedType to NamedType::ref")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    StrongInt i(42);
    addOne(i);
    REQUIRE(i.get() == 43);

    StrongInt j(42);
    addOne(StrongInt::ref(j));
    REQUIRE(j.get() == 43);
}

TEST_CASE("Default construction")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    StrongInt strongInt;
    strongInt.get() = 42;
    REQUIRE(strongInt.get() == 42);
}

template<typename Function>
using Comparator = fluent::NamedType<Function, struct ComparatorParameter>;

template <typename Function>
std::string performAction(Comparator<Function> comp)
{
    return comp.get()();
}

TEST_CASE("Strong generic type")
{
    REQUIRE(performAction(fluent::make_named<Comparator>([](){ return std::string("compare"); })) == "compare");
}

TEST_CASE("Addable")
{
    using AddableType = fluent::NamedType<int, struct AddableTag, fluent::Addable>;
    AddableType s1(12);
    AddableType s2(10);
    REQUIRE((s1 + s2).get() == 22);
    REQUIRE((+s1).get() == 12);
}

TEST_CASE("BinaryAddable")
{
    using BinaryAddableType = fluent::NamedType<int, struct BinaryAddableTag, fluent::BinaryAddable>;
    BinaryAddableType s1(12);
    BinaryAddableType s2(10);
    REQUIRE((s1 + s2).get() == 22);
}

TEST_CASE("UnaryAddable")
{
    using UnaryAddableType = fluent::NamedType<int, struct UnaryAddableTag, fluent::UnaryAddable>;
    UnaryAddableType s1(12);
    REQUIRE((+s1).get() == 12);
}

TEST_CASE("Subtractable")
{
    using SubtractableType = fluent::NamedType<int, struct SubtractableTag, fluent::Subtractable>;
    SubtractableType s1(12);
    SubtractableType s2(10);
    REQUIRE((s1 - s2).get() == 2);
    REQUIRE((-s1).get() == -12);
}

TEST_CASE("BinarySubtractable")
{
    using BinarySubtractableType = fluent::NamedType<int, struct BinarySubtractableTag, fluent::BinarySubtractable>;
    BinarySubtractableType s1(12);
    BinarySubtractableType s2(10);
    REQUIRE((s1 - s2).get() == 2);
}

TEST_CASE("UnarySubtractable")
{
    using UnarySubtractableType = fluent::NamedType<int, struct UnarySubtractableTag, fluent::UnarySubtractable>;
    UnarySubtractableType s(12);
    REQUIRE((-s).get() == -12);
}

TEST_CASE("Multiplicable")
{
    using MultiplicableType = fluent::NamedType<int, struct MultiplicableTag, fluent::Multiplicable>;
    MultiplicableType s1(12);
    MultiplicableType s2(10);
    REQUIRE((s1 * s2).get() == 120);
}

TEST_CASE("Negatable")
{
  using NegatableType = fluent::NamedType<int, struct NegatableTag, fluent::Negatable>;
  NegatableType value(10);
  REQUIRE((-value).get() == -10);
}

TEST_CASE("Comparable")
{
    REQUIRE((10_meter == 10_meter));
    REQUIRE(!(10_meter == 11_meter));
    REQUIRE((10_meter != 11_meter));
    REQUIRE(!(10_meter != 10_meter));
    REQUIRE((10_meter <  11_meter));
    REQUIRE(!(10_meter <  10_meter));
    REQUIRE((10_meter <= 10_meter));
    REQUIRE((10_meter <= 11_meter));
    REQUIRE(!(10_meter <= 9_meter));
    REQUIRE((11_meter >  10_meter));
    REQUIRE(!(10_meter > 11_meter));
    REQUIRE((11_meter >= 10_meter));
    REQUIRE((10_meter >= 10_meter));
    REQUIRE(!(9_meter >= 10_meter));
}

TEST_CASE("ConvertibleWithOperator")
{
    struct B
    {
        B(int x) : x(x) {}
        int x;
    };

    struct A
    {
        A(int x) : x(x) {}
        operator B () const { return B(x);}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleWithConstructor")
{
    struct A
    {
        A(int x) : x(x) {}
        int x;
    };

    struct B
    {
        B(A a) : x(a.x) {}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleToItself")
{
    using MyInt = fluent::NamedType<int, struct MyIntTag, fluent::ImplicitlyConvertibleTo<int>::templ>;
    MyInt myInt(42);
    int i = myInt;
    REQUIRE(i == 42);
}

TEST_CASE("Hash")
{
    using SerialNumber = fluent::NamedType<std::string, struct SerialNumberTag, fluent::Comparable, fluent::Hashable>;

    std::unordered_map<SerialNumber, int> hashMap = { {SerialNumber{"AA11"}, 10}, {SerialNumber{"BB22"}, 20} };
    SerialNumber cc33{"CC33"};
    hashMap[cc33] = 30;
    REQUIRE(hashMap[SerialNumber{"AA11"}] == 10);
    REQUIRE(hashMap[SerialNumber{"BB22"}] == 20);
    REQUIRE(hashMap[cc33] == 30);
}

struct testFunctionCallable_A
{
    testFunctionCallable_A(int x) : x(x) {}
    testFunctionCallable_A(testFunctionCallable_A const&) = delete; // ensures that passing the argument to a function doesn't make a copy
    testFunctionCallable_A(testFunctionCallable_A&&) = default;
    testFunctionCallable_A& operator+=(testFunctionCallable_A const& other) { x += other.x; return *this; }
    int x;
};

testFunctionCallable_A operator+(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return testFunctionCallable_A(a1.x + a2.x);
}

bool operator==(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return a1.x == a2.x;
}

TEST_CASE("Function callable")
{
    using A = testFunctionCallable_A;
    auto functionTakingA = [](A const& a){ return a.x; };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::FunctionCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A(42));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(functionTakingA(constStrongA) == 42);
    REQUIRE(strongA + strongA == 84);
}

TEST_CASE("Method callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::MethodCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method or function doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    auto functionTakingA = [](A const& a){ return a.constMethod(); };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::Callable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Named arguments")
{
    using FirstName = fluent::NamedType<std::string, struct FirstNameTag>;
    using LastName = fluent::NamedType<std::string, struct LastNameTag>;
    static const FirstName::argument firstName;
    static const LastName::argument lastName;
    auto getFullName = [](FirstName const& firstName, LastName const& lastName)
    {
        return firstName.get() + lastName.get();
    };

    auto fullName = getFullName(firstName = "James", lastName = "Bond");
    REQUIRE(fullName == "JamesBond");
}

TEST_CASE("Named arguments with bracket constructor")
{
    using Numbers = fluent::NamedType<std::vector<int>, struct NumbersTag>;
    static const Numbers::argument numbers;
    auto getNumbers = [](Numbers const& numbers)
    {
        return numbers.get();
    };

    auto vec = getNumbers(numbers = {1, 2, 3});
    REQUIRE(vec == std::vector<int>{1, 2, 3});
}

TEST_CASE("Empty base class optimization")
{
    REQUIRE(sizeof(Meter) == sizeof(double));
}
<|endoftext|>


<commit_before>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * main.cpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#include "bit_by_bit.hpp"

void reusable_array_test();
void byte_array_test();
void multithread_test(size_t num);
void range_test();

int main(int argc, char *argv[]) {
    reusable_array_test();
    byte_array_test();
    multithread_test(4);
    range_test();
}

#pragma mark reusable_array_test

#include <cassert>
#include <iostream>

struct particle {
    int life_time;
    int age;
    int name;

    particle() {}
    particle(int life_time, int name)
        : life_time(life_time)
        , name(name)
        , age(0) {}

    void init(int life_time, int name) {
        this->life_time = life_time;
        this->name = name;
        this->age = 0;
    }

    bool update() {
        return ++age < life_time;
    }

    void print() const {
        std::cout << name << ", " << (life_time - age) << std::endl;
    }
};

constexpr int loop_num(1);
constexpr int elem_num(10);

void reusable_array_test() {
    bbb::random::set_seed_mt(0);
    auto a = bbb::random::mt();
    bbb::random::set_seed_mt(0);
    auto b = bbb::random::mt();
    bbb::random::set_seed_mt(1);
    auto c = bbb::random::mt();
    assert(a == b);
    assert(a != c);

    bbb::stop_watch watch;
    watch.start();

    {
        bbb::random::set_seed_mt(0);
        bbb::reusable_array<particle, elem_num> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            do f.init(bbb::random::mt() % 100, f.current_size()); while(f.has_space());
            while(f.current_size()) {
                f.update();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }

    {
        bbb::random::set_seed_mt(0);
        bbb::shared_vector<particle> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            for(; f.size() < elem_num; f.push_back(std::shared_ptr<particle>(new particle(rand() % 100, f.size()))));
            auto wrapper = bbb::make_reverse(f);
            while(f.size()) for(auto e : wrapper) if(!e->update()) {
                e = f.back();
                f.pop_back();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }
}

void byte_array_test() {
    bbb::byte_array<int> barr{0x7FFFFFFF};
    for(auto i = 0; i < barr.size(); i++) {
        std::cout << (int)barr[i] << std::endl;
    }
};

void multithread_test(size_t num) {
    size_t sum = 0;
    bool is_run = true;
    bbb::stop_watch watch;
    watch.start();
    bbb::multithread::manager manager(num, [&sum, &is_run](size_t index, std::mutex &mutex) {
        while(is_run) {
            if(mutex.try_lock()) {
                sum++;
                mutex.unlock();
            }
            bbb::sleep_nanoseconds(50);
        }
    });

    while(is_run) {
        bbb::sleep_milliseconds(10);
        auto lock(manager.lock_guard());
        if(100000 < sum) {
            is_run = false;
            manager.join();
        }
    }
    watch.rap();
    std::cout << "time: " << watch.getLastRapMilliseconds() << std::endl;
}

void range_test() {
    {
        std::vector<int> vec;
        for(auto i : bbb::range(2, 10)) {
            vec.push_back(i);
        }

        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
            v.value *= 2;
        }
        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }

    {
        const std::vector<int> cvec{1, 2, 3};
        for(auto v : bbb::enumerate(cvec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }
    std::cout << std::endl;

    std::vector<std::string> svec{"a", "hoge", "foo"};
    for(auto v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
}<commit_msg>update test<commit_after>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * main.cpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#include "bit_by_bit.hpp"

void reusable_array_test();
void byte_array_test();
void multithread_test(size_t num);
void range_test();

int main(int argc, char *argv[]) {
    reusable_array_test();
    byte_array_test();
    multithread_test(4);
    range_test();
}

#pragma mark reusable_array_test

#include <cassert>
#include <iostream>

struct particle {
    int life_time;
    int age;
    int name;

    particle() {}
    particle(int life_time, int name)
        : life_time(life_time)
        , name(name)
        , age(0) {}

    void init(int life_time, int name) {
        this->life_time = life_time;
        this->name = name;
        this->age = 0;
    }

    bool update() {
        return ++age < life_time;
    }

    void print() const {
        std::cout << name << ", " << (life_time - age) << std::endl;
    }
};

constexpr int loop_num(1);
constexpr int elem_num(10);

void reusable_array_test() {
    bbb::random::set_seed_mt(0);
    auto a = bbb::random::mt();
    bbb::random::set_seed_mt(0);
    auto b = bbb::random::mt();
    bbb::random::set_seed_mt(1);
    auto c = bbb::random::mt();
    assert(a == b);
    assert(a != c);

    bbb::stop_watch watch;
    watch.start();

    {
        bbb::random::set_seed_mt(0);
        bbb::reusable_array<particle, elem_num> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            do f.init(bbb::random::mt() % 100, f.current_size()); while(f.has_space());
            while(f.current_size()) {
                f.update();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }

    {
        bbb::random::set_seed_mt(0);
        bbb::shared_vector<particle> f;
        watch.rap();

        for(int k = 0; k++ < loop_num;) {
            for(; f.size() < elem_num; f.push_back(std::shared_ptr<particle>(new particle(rand() % 100, f.size()))));
            auto wrapper = bbb::make_reverse(f);
            while(f.size()) for(auto e : wrapper) if(!e->update()) {
                e = f.back();
                f.pop_back();
            }
        }

        watch.rap();
        std::cout << "time: " << watch.getLastRapNanoseconds() << std::endl;
    }
}

void byte_array_test() {
    bbb::byte_array<int> barr{0x7FFFFFFF};
    for(auto i = 0; i < barr.size(); i++) {
        std::cout << (int)barr[i] << std::endl;
    }
};

void multithread_test(size_t num) {
    size_t sum = 0;
    bool is_run = true;
    bbb::stop_watch watch;
    watch.start();
    bbb::multithread::manager manager(num, [&sum, &is_run](size_t index, std::mutex &mutex) {
        while(is_run) {
            if(mutex.try_lock()) {
                sum++;
                mutex.unlock();
            }
            bbb::sleep_nanoseconds(50);
        }
    });

    while(is_run) {
        bbb::sleep_milliseconds(10);
        auto lock(manager.lock_guard());
        if(100000 < sum) {
            is_run = false;
            manager.join();
        }
    }
    watch.rap();
    std::cout << "time: " << watch.getLastRapMilliseconds() << std::endl;
}

void range_test() {
    {
        std::vector<int> vec;
        for(auto i : bbb::range(2, 10)) {
            vec.push_back(i);
        }

        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
            v.value *= 2;
        }
        for(auto v : bbb::enumerate(vec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }

    {
        const std::vector<int> cvec{1, 2, 3};
        for(auto v : bbb::enumerate(cvec)) {
            std::cout << v.index << ", " << v.value << std::endl;
        }
    }
    std::cout << std::endl;

    std::vector<std::string> svec{"a", "hoge", "foo"};
    for(auto &v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
    for(const auto &v : bbb::enumerate(svec)) {
        std::cout << v.index << ", " << v.value << std::endl;
    }
}<|endoftext|>


<commit_before>bcc55685-ad5a-11e7-97f1-ac87a332f658<commit_msg>My Life for Auir<commit_after>bd8904a1-ad5a-11e7-beb0-ac87a332f658<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008-2009      Patrick Spendrin  <ps_ml@gmx.de>
// Copyright 2010           Thibaut Gridel <tgridel@free.fr>
//

#include "GeometryLayer.h"

// Marble
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataLineStyle.h"
#include "GeoDataObject.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolygon.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "MarbleDebug.h"
#include "GeoDataTypes.h"
#include "GeoDataFeature.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "GeoGraphicsScene.h"
#include "GeoGraphicsItem.h"
#include "GeoLineStringGraphicsItem.h"
#include "GeoPolygonGraphicsItem.h"

// Qt
#include <QtCore/QTime>
#include <QtCore/QAbstractItemModel>

namespace Marble
{
int GeometryLayer::s_defaultZValues[GeoDataFeature::LastIndex];
int GeometryLayer::s_defaultLODValues[GeoDataFeature::LastIndex];
bool GeometryLayer::s_defaultValuesInitialized = false;
int GeometryLayer::s_defaultZValue = 50;

class GeometryLayerPrivate
{
public:
    void createGraphicsItems( GeoDataObject *object );
    void createGraphicsItemFromGeometry( GeoDataGeometry *object, GeoDataPlacemark *placemark );

    QBrush m_currentBrush;
    QPen m_currentPen;
    GeoGraphicsScene m_scene;
    QAbstractItemModel *m_model;
};

GeometryLayer::GeometryLayer( QAbstractItemModel *model )
        : d( new GeometryLayerPrivate() )
{
    if ( !s_defaultValuesInitialized )
        initializeDefaultValues();

    d->m_model = model;
    GeoDataObject *object = static_cast<GeoDataObject*>( d->m_model->index( 0, 0, QModelIndex() ).internalPointer() );
    if ( object && object->parent() )
        d->createGraphicsItems( object->parent() );
}

GeometryLayer::~GeometryLayer()
{
    delete d;
}

QStringList GeometryLayer::renderPosition() const
{
    return QStringList( "HOVERS_ABOVE_SURFACE" );
}

void GeometryLayer::initializeDefaultValues()
{
    for ( int i = 0; i < GeoDataFeature::LastIndex; i++ )
        s_defaultZValues[i] = s_defaultZValue;

    for ( int i = 0; i < GeoDataFeature::LastIndex; i++ )
        s_defaultLODValues[i] = -1;

    s_defaultZValues[GeoDataFeature::None]                = 0;
    s_defaultZValues[GeoDataFeature::NaturalWater]        = s_defaultZValue - 15;
    s_defaultZValues[GeoDataFeature::NaturalWood]         = s_defaultZValue - 14;

    s_defaultZValues[GeoDataFeature::TransportParking]    = s_defaultZValue - 13;

    s_defaultZValues[GeoDataFeature::HighwayTertiaryLink] = s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwaySecondaryLink]= s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwayPrimaryLink]  = s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwayTrunkLink]    = s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwayMotorwayLink] = s_defaultZValue - 12;

    s_defaultZValues[GeoDataFeature::HighwayUnknown]      = s_defaultZValue - 11;
    s_defaultZValues[GeoDataFeature::HighwayPath]         = s_defaultZValue - 10;
    s_defaultZValues[GeoDataFeature::HighwayTrack]        = s_defaultZValue - 9;
    s_defaultZValues[GeoDataFeature::HighwayPedestrian]   = s_defaultZValue - 8;
    s_defaultZValues[GeoDataFeature::HighwayService]      = s_defaultZValue - 7;
    s_defaultZValues[GeoDataFeature::HighwayRoad]         = s_defaultZValue - 6;
    s_defaultZValues[GeoDataFeature::HighwayTertiary]     = s_defaultZValue - 5;
    s_defaultZValues[GeoDataFeature::HighwaySecondary]    = s_defaultZValue - 4;
    s_defaultZValues[GeoDataFeature::HighwayPrimary]      = s_defaultZValue - 3;
    s_defaultZValues[GeoDataFeature::HighwayTrunk]        = s_defaultZValue - 2;
    s_defaultZValues[GeoDataFeature::HighwayMotorway]     = s_defaultZValue - 1;

    s_defaultValuesInitialized = true;
}

bool GeometryLayer::render( GeoPainter *painter, ViewportParams *viewport,
                            const QString& renderPos, GeoSceneLayer * layer )
{
//    QTime t;
//    t.start();
//    mDebug() << "rendering " << m_root;
    /*if ( d->m_root )
    {
        d->renderGeoDataObject( painter, d->m_root, viewport );
    }*/
//    mDebug() << "rendering geometry: " << t.elapsed();
    QList<GeoGraphicsItem*> items = d->m_scene.items( viewport->viewLatLonAltBox() );
    foreach( GeoGraphicsItem* item, items )
    {
        if ( item->visible() )
            item->paint( painter, viewport, renderPos, layer );
    }
    return true;
}

void GeometryLayerPrivate::createGraphicsItems( GeoDataObject *object )
{
    GeoDataFeature *feature = dynamic_cast<GeoDataFeature*>( object );

    if ( dynamic_cast<GeoDataPlacemark*>( object ) )
    {
        GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>( object );
        createGraphicsItemFromGeometry( placemark->geometry(), placemark );
    }

    // parse all child objects of the container
    GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( object );
    if ( container )
    {
        int rowCount = container->size();
        for ( int row = 0; row < rowCount; ++row )
        {
            createGraphicsItems( container->child( row ) );
        }
    }
}

void GeometryLayerPrivate::createGraphicsItemFromGeometry( GeoDataGeometry* object, GeoDataPlacemark *placemark )
{
    GeoGraphicsItem *item = 0;
    if ( dynamic_cast<GeoDataLinearRing*>( object ) )
    {
    }
    else if ( GeoDataLineString* line = dynamic_cast<GeoDataLineString*>( object ) )
    {
        item = new GeoLineStringGraphicsItem();
        static_cast<GeoLineStringGraphicsItem*>( item )->setLineString( *line );
    }
    else if ( GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( object ) )
    {
        item = new GeoPolygonGraphicsItem();
        static_cast<GeoPolygonGraphicsItem*>( item )->setPolygon( *poly );
    }
    else if ( dynamic_cast<GeoDataMultiGeometry*>( object ) )
    {
        GeoDataMultiGeometry *multigeo = dynamic_cast<GeoDataMultiGeometry*>( object );
        int rowCount = multigeo->size();
        for ( int row = 0; row < rowCount; ++row )
        {
            createGraphicsItemFromGeometry( multigeo->child( row ), placemark );
        }
    }
    if ( !item )
        return;
    item->setStyle( placemark->style() );
    item->setVisible( placemark->isVisible() );
    item->setZValue( GeometryLayer::s_defaultZValues[placemark->visualCategory()] );
    item->setMinLodPixels( GeometryLayer::s_defaultLODValues[placemark->visualCategory()] );
    m_scene.addIdem( item );
}

void GeometryLayer::invalidateScene()
{
    QList<GeoGraphicsItem*> items = d->m_scene.items();
    foreach( GeoGraphicsItem* item, items )
    {
        delete item;
    }
    d->m_scene.clear();
    GeoDataObject *object = static_cast<GeoDataObject*>( d->m_model->index( 0, 0, QModelIndex() ).internalPointer() );
    if ( object && object->parent() )
        d->createGraphicsItems( object->parent() );
}

}

#include "GeometryLayer.moc"
<commit_msg>Map Quality in GeometryLayer.<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2008-2009      Patrick Spendrin  <ps_ml@gmx.de>
// Copyright 2010           Thibaut Gridel <tgridel@free.fr>
//

#include "GeometryLayer.h"

// Marble
#include "GeoDataDocument.h"
#include "GeoDataFolder.h"
#include "GeoDataLineStyle.h"
#include "GeoDataObject.h"
#include "GeoDataPlacemark.h"
#include "GeoDataPolygon.h"
#include "GeoDataPolyStyle.h"
#include "GeoDataStyle.h"
#include "GeoDataStyleMap.h"
#include "MarbleDebug.h"
#include "GeoDataTypes.h"
#include "GeoDataFeature.h"
#include "GeoPainter.h"
#include "ViewportParams.h"
#include "GeoGraphicsScene.h"
#include "GeoGraphicsItem.h"
#include "GeoLineStringGraphicsItem.h"
#include "GeoPolygonGraphicsItem.h"

// Qt
#include <QtCore/QTime>
#include <QtCore/QAbstractItemModel>

namespace Marble
{
int GeometryLayer::s_defaultZValues[GeoDataFeature::LastIndex];
int GeometryLayer::s_defaultLODValues[GeoDataFeature::LastIndex];
bool GeometryLayer::s_defaultValuesInitialized = false;
int GeometryLayer::s_defaultZValue = 50;

class GeometryLayerPrivate
{
public:
    void createGraphicsItems( GeoDataObject *object );
    void createGraphicsItemFromGeometry( GeoDataGeometry *object, GeoDataPlacemark *placemark );

    QBrush m_currentBrush;
    QPen m_currentPen;
    GeoGraphicsScene m_scene;
    QAbstractItemModel *m_model;
};

GeometryLayer::GeometryLayer( QAbstractItemModel *model )
        : d( new GeometryLayerPrivate() )
{
    if ( !s_defaultValuesInitialized )
        initializeDefaultValues();

    d->m_model = model;
    GeoDataObject *object = static_cast<GeoDataObject*>( d->m_model->index( 0, 0, QModelIndex() ).internalPointer() );
    if ( object && object->parent() )
        d->createGraphicsItems( object->parent() );
}

GeometryLayer::~GeometryLayer()
{
    delete d;
}

QStringList GeometryLayer::renderPosition() const
{
    return QStringList( "HOVERS_ABOVE_SURFACE" );
}

void GeometryLayer::initializeDefaultValues()
{
    for ( int i = 0; i < GeoDataFeature::LastIndex; i++ )
        s_defaultZValues[i] = s_defaultZValue;

    for ( int i = 0; i < GeoDataFeature::LastIndex; i++ )
        s_defaultLODValues[i] = -1;

    s_defaultZValues[GeoDataFeature::None]                = 0;
    s_defaultZValues[GeoDataFeature::NaturalWater]        = s_defaultZValue - 15;
    s_defaultZValues[GeoDataFeature::NaturalWood]         = s_defaultZValue - 14;

    s_defaultZValues[GeoDataFeature::TransportParking]    = s_defaultZValue - 13;

    s_defaultZValues[GeoDataFeature::HighwayTertiaryLink] = s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwaySecondaryLink]= s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwayPrimaryLink]  = s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwayTrunkLink]    = s_defaultZValue - 12;
    s_defaultZValues[GeoDataFeature::HighwayMotorwayLink] = s_defaultZValue - 12;

    s_defaultZValues[GeoDataFeature::HighwayUnknown]      = s_defaultZValue - 11;
    s_defaultZValues[GeoDataFeature::HighwayPath]         = s_defaultZValue - 10;
    s_defaultZValues[GeoDataFeature::HighwayTrack]        = s_defaultZValue - 9;
    s_defaultZValues[GeoDataFeature::HighwayPedestrian]   = s_defaultZValue - 8;
    s_defaultZValues[GeoDataFeature::HighwayService]      = s_defaultZValue - 7;
    s_defaultZValues[GeoDataFeature::HighwayRoad]         = s_defaultZValue - 6;
    s_defaultZValues[GeoDataFeature::HighwayTertiary]     = s_defaultZValue - 5;
    s_defaultZValues[GeoDataFeature::HighwaySecondary]    = s_defaultZValue - 4;
    s_defaultZValues[GeoDataFeature::HighwayPrimary]      = s_defaultZValue - 3;
    s_defaultZValues[GeoDataFeature::HighwayTrunk]        = s_defaultZValue - 2;
    s_defaultZValues[GeoDataFeature::HighwayMotorway]     = s_defaultZValue - 1;

    s_defaultValuesInitialized = true;
}

bool GeometryLayer::render( GeoPainter *painter, ViewportParams *viewport,
                            const QString& renderPos, GeoSceneLayer * layer )
{
    painter->save();
    painter->autoMapQuality();
    QList<GeoGraphicsItem*> items = d->m_scene.items( viewport->viewLatLonAltBox() );
    foreach( GeoGraphicsItem* item, items )
    {
        if ( item->visible() )
            item->paint( painter, viewport, renderPos, layer );
    }
    painter->restore();
    return true;
}

void GeometryLayerPrivate::createGraphicsItems( GeoDataObject *object )
{
    GeoDataFeature *feature = dynamic_cast<GeoDataFeature*>( object );

    if ( dynamic_cast<GeoDataPlacemark*>( object ) )
    {
        GeoDataPlacemark *placemark = static_cast<GeoDataPlacemark*>( object );
        createGraphicsItemFromGeometry( placemark->geometry(), placemark );
    }

    // parse all child objects of the container
    GeoDataContainer *container = dynamic_cast<GeoDataContainer*>( object );
    if ( container )
    {
        int rowCount = container->size();
        for ( int row = 0; row < rowCount; ++row )
        {
            createGraphicsItems( container->child( row ) );
        }
    }
}

void GeometryLayerPrivate::createGraphicsItemFromGeometry( GeoDataGeometry* object, GeoDataPlacemark *placemark )
{
    GeoGraphicsItem *item = 0;
    if ( dynamic_cast<GeoDataLinearRing*>( object ) )
    {
    }
    else if ( GeoDataLineString* line = dynamic_cast<GeoDataLineString*>( object ) )
    {
        item = new GeoLineStringGraphicsItem();
        static_cast<GeoLineStringGraphicsItem*>( item )->setLineString( *line );
    }
    else if ( GeoDataPolygon *poly = dynamic_cast<GeoDataPolygon*>( object ) )
    {
        item = new GeoPolygonGraphicsItem();
        static_cast<GeoPolygonGraphicsItem*>( item )->setPolygon( *poly );
    }
    else if ( dynamic_cast<GeoDataMultiGeometry*>( object ) )
    {
        GeoDataMultiGeometry *multigeo = dynamic_cast<GeoDataMultiGeometry*>( object );
        int rowCount = multigeo->size();
        for ( int row = 0; row < rowCount; ++row )
        {
            createGraphicsItemFromGeometry( multigeo->child( row ), placemark );
        }
    }
    if ( !item )
        return;
    item->setStyle( placemark->style() );
    item->setVisible( placemark->isVisible() );
    item->setZValue( GeometryLayer::s_defaultZValues[placemark->visualCategory()] );
    item->setMinLodPixels( GeometryLayer::s_defaultLODValues[placemark->visualCategory()] );
    m_scene.addIdem( item );
}

void GeometryLayer::invalidateScene()
{
    QList<GeoGraphicsItem*> items = d->m_scene.items();
    foreach( GeoGraphicsItem* item, items )
    {
        delete item;
    }
    d->m_scene.clear();
    GeoDataObject *object = static_cast<GeoDataObject*>( d->m_model->index( 0, 0, QModelIndex() ).internalPointer() );
    if ( object && object->parent() )
        d->createGraphicsItems( object->parent() );
}

}

#include "GeometryLayer.moc"
<|endoftext|>


<commit_before>8129aa97-2749-11e6-be60-e0f84713e7b8<commit_msg>Now it no longer crashes if X<commit_after>81387b7d-2749-11e6-8475-e0f84713e7b8<|endoftext|>


<commit_before>/*
** This source file is part of framepacker
**
** For the latest info, see https://github.com/paladin-t/framepacker/
**
** Copyright (C) 2015 Wang Renxin
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of
** this software and associated documentation files (the "Software"), to deal in
** the Software without restriction, including without limitation the rights to
** use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
** the Software, and to permit persons to whom the Software is furnished to do so,
** subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "framepacker.hpp"
#include <list>
#include <string>
#include <Windows.h>
#include "third/freeimage/freeimage.h"

using namespace framepacker;

namespace framepacker {

struct color {
	color() : r(0), g(0), b(0), a(0) {
	}
	color(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) : r(_r), g(_g), b(_b), a(_a) {
	}

	bool is_transparent(void) const {
		return a == 0;
	}

	unsigned char r;
	unsigned char g;
	unsigned char b;
	unsigned char a;
};

class freeimage {

public:
	freeimage() : handle(NULL), w(0), h(0) {
	}
	freeimage(const char* p) {
		load_file(p);
	}
	~freeimage() {
		unload();
	}

	const char* get_path(void) const { return path.c_str(); }

	int width(void) const { return w; }
	int height(void) const { return h; }

	BYTE* bytes(void) const { return FreeImage_GetBits(handle); }

	color pixel(unsigned x, unsigned y) const {
		RGBQUAD col;
		FreeImage_GetPixelColor(handle, x, y, &col);
		color ret;
		ret.r = col.rgbRed;
		ret.g = col.rgbGreen;
		ret.b = col.rgbBlue;
		ret.a = col.rgbReserved;

		return ret;
	}
	void pixel(unsigned x, unsigned y, color &c) {
		RGBQUAD col;
		col.rgbRed = c.r;
		col.rgbGreen = c.g;
		col.rgbBlue = c.b;
		col.rgbReserved = c.a;
		FreeImage_SetPixelColor(handle, x, y, &col);
	}

	void copy_from(freeimage &src, unsigned left, unsigned top, unsigned width, unsigned height, unsigned x, unsigned y) {
		FIBITMAP* fib = FreeImage_Copy(src.handle, left, top, left + width, top + height);
		FreeImage_Paste(handle, fib, x, y, 255);
		FreeImage_Unload(fib);
	}

	bool is_transparent(unsigned x, unsigned y) const {
		color c = pixel(x, y);

		return c.is_transparent();
	}

	bool resize(int _w, int _h) {
		unload();
		handle = FreeImage_Allocate(_w, _h, 32);
		w = _w;
		h = _h;

		return true;
	}

	bool load_file(const char* p) {
		path = p;

		handle = NULL;
		w = 0;
		h = 0;

		FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(path.c_str());
		if(fif != FIF_UNKNOWN) {
			handle = FreeImage_Load(fif, path.c_str());
			if (FreeImage_GetBPP(handle) != 32)  {
				FIBITMAP* tmp = handle;
				handle = FreeImage_ConvertTo32Bits(tmp);
			}

			w = FreeImage_GetWidth(handle);
			h = FreeImage_GetHeight(handle);

			return true;
		}

		return false;
	}

	void unload(void) {
		if(!handle)
			return;

		FreeImage_Unload(handle);
		handle = NULL;
	}

	void save(const char* p) {
		FreeImage_Save(FIF_PNG, handle, p);
	}

private:
	std::string path;
	FIBITMAP* handle;
	unsigned w;
	unsigned h;

};

}

typedef packer<freeimage> packer_type;

#define _BIN_FILE_NAME "framepacker"

#define _CHECK_ARG(__c, __i, __e) \
	do { \
		if(__c <= __i + 1) { \
			printf(__e); \
			return; \
		} \
	} while(0)

static unsigned short _set_console_color(unsigned short col) {
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
	if(!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbiInfo)) {
		printf("GetConsoleScreenBufferInfo error!\n");

		return 0;
	}
	if(!SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col)) {
		printf("SetConsoleTextAttribute error!\n");

		return 0;
	}

	return csbiInfo.wAttributes;
}

struct ConsoleColor {
	ConsoleColor(unsigned short col) {
		old = _set_console_color(col);
	}
	~ConsoleColor() {
		_set_console_color(old);
	}

	unsigned short old;
};

#define CONSOLE_COLOR(C) ConsoleColor __##__FUNCTION__##__LINE__(C);

static void _show_tip(void) {
	printf("[Usage]\n");
	printf("  %s FILE_LIST [-o output_file] [OPTIONS] - Packs some images\n", _BIN_FILE_NAME);
	printf("\n");
	printf("  FILE_LIST := file*\n");
	printf("  OPTIONS   := -p n    : Padding, 1 as default\n");
	printf("            := -s mxn  : Expected texture size, eg. 256x512, may enlarge result\n");
	printf("            := -t      : Disable rotation\n");
	printf("            := -w      : Disable forcing texture to POT (Power of 2)\n");
	printf("            := -m      : Disable alpha trim\n");
}

static void _process_parameters(int argc, char* argv[]) {
	int i = 1;
	std::string m = "\0";
	int padding = 1;
	int w = 0, h = 0;
	bool allow_rotate = true;
	bool power_of_2 = true;
	bool alpha_trim = true;

	std::list<std::string> inputs;
	std::list<std::pair<std::string, std::string> > options;

	// Parses arguments.
	while(i < argc) {
		if(!memcmp(argv[i], "-", 1)) {
			if(!memcmp(argv[i] + 1, "o", 1)) {
				m = 'o';
				_CHECK_ARG(argc, i, "-o: File name expected.\n");
				options.push_back(std::make_pair(m, argv[++i]));
				++i;
			} else if(!memcmp(argv[i] + 1, "p", 1)) {
				_CHECK_ARG(argc, i, "-p: Padding size expected.\n");
				padding = max(std::atoi(argv[++i]), 0);
			} else if(!memcmp(argv[i] + 1, "s", 1)) {
				_CHECK_ARG(argc, i, "-s: Size expected.\n");
				char buf[256];
				_snprintf_s(buf, sizeof(buf), argv[++i]);
				char* ctx = NULL;
				char* tmp = strtok_s(buf, "x", &ctx);
				w = std::atoi(tmp);
				h = std::atoi(ctx);
				++i;
			} else if(!memcmp(argv[i] + 1, "t", 1)) {
				allow_rotate = false;
				++i;
			} else if(!memcmp(argv[i] + 1, "w", 1)) {
				power_of_2 = false;
				++i;
			} else if(!memcmp(argv[i] + 1, "m", 1)) {
				alpha_trim = false;
				++i;
			} else {
				printf("Unknown argument: %s.\n", argv[i++]);
			}
		} else {
			inputs.push_back(argv[i++]);
		}
	}

	// Tells output path.
	std::string outpath = "output.png";
	for(auto it = options.begin(); it != options.end(); ++it) {
		if(it->first == "o")
			outpath = it->second;
	}

	// Prepares packing.
	DWORD time = GetTickCount();

	packer_type packer;
	packer.padding = padding;
	packer.output_texture_size = vec2(w, h);
	packer.allow_rotate = allow_rotate;
	packer.power_of_2 = power_of_2;
	packer.alpha_trim = alpha_trim;
	packer.comparer = packer_type::compare_area;

	for(auto it = inputs.begin(); it != inputs.end(); ++it) {
		packer_type::texture_type img(new freeimage(it->c_str()));

		packer.add(it->c_str(), img);
	}

	DWORD load_time = GetTickCount() - time;
	time = GetTickCount();

	// Packs it.
	packer_type::texture_type result(new freeimage);
	packer_type::texture_coll_type packed;
	packer_type::texture_coll_type failed;
	packer.pack(result, packed, failed);

	DWORD pack_time = GetTickCount() - time;

	// Prompts.
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		printf("Packed %d:\n", packed.size());
		for(auto it = packed.begin(); it != packed.end(); ++it) {
			packer_type::block_type &blk = it->second;
			printf("  %s [%d, %d] - [%d, %d]\n", it->first.c_str(), blk.fit->min_x(), blk.fit->min_y(), blk.fit->min_x() + blk.fit->width(), blk.fit->min_y() + blk.fit->height());
		}
	}
	if(failed.size()) {
		CONSOLE_COLOR(FOREGROUND_RED | FOREGROUND_GREEN);
		printf("Failed %d:\n", failed.size());
		for(auto it = failed.begin(); it != failed.end(); ++it) {
			packer_type::block_type &blk = it->second;
			printf("  %s\n", it->first.c_str());
		}
	}
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		printf("Cost time: %gs loading; %gs packing.\n", (float)load_time / 1000.0f, (float)pack_time / 1000.0f);
	}

	// Serializes.
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		std::string out_tex = outpath + ".png";
		result->save(out_tex.c_str());
		printf("Texture written: %s.\n", out_tex.c_str());
	}
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		std::string out_meta = outpath + ".json";
		std::ofstream fs(out_meta);
		packer.write_meta(fs, packed, result, outpath.c_str());
		fs.close();
		printf("Meta data written: %s.\n", out_meta.c_str());
	}
}

static void _on_startup(void) {
	FreeImage_Initialise();
}

static void _on_exit(void) {
	FreeImage_DeInitialise();
}

int main(int argc, char* argv[]) {
	atexit(_on_exit);

	_on_startup();

	if(argc == 1)
		_show_tip();
	else if(argc >= 2)
		_process_parameters(argc, argv);

	return 0;
}
<commit_msg>*updated main.cpp.<commit_after>/*
** This source file is part of framepacker
**
** For the latest info, see https://github.com/paladin-t/framepacker/
**
** Copyright (C) 2015 Wang Renxin
**
** Permission is hereby granted, free of charge, to any person obtaining a copy of
** this software and associated documentation files (the "Software"), to deal in
** the Software without restriction, including without limitation the rights to
** use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
** the Software, and to permit persons to whom the Software is furnished to do so,
** subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
** FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
** COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
** IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "framepacker.hpp"
#include <list>
#include <string>
#include <Windows.h>
#include "freeimage.h"

using namespace framepacker;

namespace framepacker {

struct color {
	color() : r(0), g(0), b(0), a(0) {
	}
	color(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) : r(_r), g(_g), b(_b), a(_a) {
	}

	bool is_transparent(void) const {
		return a == 0;
	}

	unsigned char r;
	unsigned char g;
	unsigned char b;
	unsigned char a;
};

class freeimage {

public:
	freeimage() : handle(NULL), w(0), h(0) {
	}
	freeimage(const char* p) {
		load_file(p);
	}
	~freeimage() {
		unload();
	}

	const char* get_path(void) const { return path.c_str(); }

	int width(void) const { return w; }
	int height(void) const { return h; }

	BYTE* bytes(void) const { return FreeImage_GetBits(handle); }

	color pixel(unsigned x, unsigned y) const {
		RGBQUAD col;
		FreeImage_GetPixelColor(handle, x, y, &col);
		color ret;
		ret.r = col.rgbRed;
		ret.g = col.rgbGreen;
		ret.b = col.rgbBlue;
		ret.a = col.rgbReserved;

		return ret;
	}
	void pixel(unsigned x, unsigned y, color &c) {
		RGBQUAD col;
		col.rgbRed = c.r;
		col.rgbGreen = c.g;
		col.rgbBlue = c.b;
		col.rgbReserved = c.a;
		FreeImage_SetPixelColor(handle, x, y, &col);
	}

	void copy_from(freeimage &src, unsigned left, unsigned top, unsigned width, unsigned height, unsigned x, unsigned y) {
		FIBITMAP* fib = FreeImage_Copy(src.handle, left, top, left + width, top + height);
		FreeImage_Paste(handle, fib, x, y, 255);
		FreeImage_Unload(fib);
	}

	bool is_transparent(unsigned x, unsigned y) const {
		color c = pixel(x, y);

		return c.is_transparent();
	}

	bool resize(int _w, int _h) {
		unload();
		handle = FreeImage_Allocate(_w, _h, 32);
		w = _w;
		h = _h;

		return true;
	}

	bool load_file(const char* p) {
		path = p;

		handle = NULL;
		w = 0;
		h = 0;

		FREE_IMAGE_FORMAT fif = FreeImage_GetFIFFromFilename(path.c_str());
		if(fif != FIF_UNKNOWN) {
			handle = FreeImage_Load(fif, path.c_str());
			if (FreeImage_GetBPP(handle) != 32)  {
				FIBITMAP* tmp = handle;
				handle = FreeImage_ConvertTo32Bits(tmp);
			}

			w = FreeImage_GetWidth(handle);
			h = FreeImage_GetHeight(handle);

			return true;
		}

		return false;
	}

	void unload(void) {
		if(!handle)
			return;

		FreeImage_Unload(handle);
		handle = NULL;
	}

	void save(const char* p) {
		FreeImage_Save(FIF_PNG, handle, p);
	}

private:
	std::string path;
	FIBITMAP* handle;
	unsigned w;
	unsigned h;

};

}

typedef packer<freeimage> packer_type;

#define _BIN_FILE_NAME "framepacker"

#define _CHECK_ARG(__c, __i, __e) \
	do { \
		if(__c <= __i + 1) { \
			printf(__e); \
			return; \
		} \
	} while(0)

static unsigned short _set_console_color(unsigned short col) {
	CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
	if(!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbiInfo)) {
		printf("GetConsoleScreenBufferInfo error!\n");

		return 0;
	}
	if(!SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), col)) {
		printf("SetConsoleTextAttribute error!\n");

		return 0;
	}

	return csbiInfo.wAttributes;
}

struct ConsoleColor {
	ConsoleColor(unsigned short col) {
		old = _set_console_color(col);
	}
	~ConsoleColor() {
		_set_console_color(old);
	}

	unsigned short old;
};

#define CONSOLE_COLOR(C) ConsoleColor __##__FUNCTION__##__LINE__(C);

static void _show_tip(void) {
	printf("[Usage]\n");
	printf("  %s FILE_LIST [-o output_file] [OPTIONS] - Packs some images\n", _BIN_FILE_NAME);
	printf("\n");
	printf("  FILE_LIST := file*\n");
	printf("  OPTIONS   := -p n    : Padding, 1 as default\n");
	printf("            := -s mxn  : Expected texture size, eg. 256x512, may enlarge result\n");
	printf("            := -t      : Disable rotation\n");
	printf("            := -w      : Disable forcing texture to POT (Power of 2)\n");
	printf("            := -m      : Disable alpha trim\n");
}

static void _process_parameters(int argc, char* argv[]) {
	int i = 1;
	std::string m = "\0";
	int padding = 1;
	int w = 0, h = 0;
	bool allow_rotate = true;
	bool power_of_2 = true;
	bool alpha_trim = true;

	std::list<std::string> inputs;
	std::list<std::pair<std::string, std::string> > options;

	// Parses arguments.
	while(i < argc) {
		if(!memcmp(argv[i], "-", 1)) {
			if(!memcmp(argv[i] + 1, "o", 1)) {
				m = 'o';
				_CHECK_ARG(argc, i, "-o: File name expected.\n");
				options.push_back(std::make_pair(m, argv[++i]));
				++i;
			} else if(!memcmp(argv[i] + 1, "p", 1)) {
				_CHECK_ARG(argc, i, "-p: Padding size expected.\n");
				padding = max(std::atoi(argv[++i]), 0);
			} else if(!memcmp(argv[i] + 1, "s", 1)) {
				_CHECK_ARG(argc, i, "-s: Size expected.\n");
				char buf[256];
				_snprintf_s(buf, sizeof(buf), argv[++i]);
				char* ctx = NULL;
				char* tmp = strtok_s(buf, "x", &ctx);
				w = std::atoi(tmp);
				h = std::atoi(ctx);
				++i;
			} else if(!memcmp(argv[i] + 1, "t", 1)) {
				allow_rotate = false;
				++i;
			} else if(!memcmp(argv[i] + 1, "w", 1)) {
				power_of_2 = false;
				++i;
			} else if(!memcmp(argv[i] + 1, "m", 1)) {
				alpha_trim = false;
				++i;
			} else {
				printf("Unknown argument: %s.\n", argv[i++]);
			}
		} else {
			inputs.push_back(argv[i++]);
		}
	}

	// Tells output path.
	std::string outpath = "output.png";
	for(auto it = options.begin(); it != options.end(); ++it) {
		if(it->first == "o")
			outpath = it->second;
	}

	// Prepares packing.
	DWORD time = GetTickCount();

	packer_type packer;
	packer.padding = padding;
	packer.output_texture_size = vec2(w, h);
	packer.allow_rotate = allow_rotate;
	packer.power_of_2 = power_of_2;
	packer.alpha_trim = alpha_trim;
	packer.comparer = packer_type::compare_area;

	for(auto it = inputs.begin(); it != inputs.end(); ++it) {
		packer_type::texture_type img(new freeimage(it->c_str()));

		packer.add(it->c_str(), img);
	}

	DWORD load_time = GetTickCount() - time;
	time = GetTickCount();

	// Packs it.
	packer_type::texture_type result(new freeimage);
	packer_type::texture_coll_type packed;
	packer_type::texture_coll_type failed;
	packer.pack(result, packed, failed);

	DWORD pack_time = GetTickCount() - time;

	// Prompts.
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		printf("Packed %d:\n", packed.size());
		for(auto it = packed.begin(); it != packed.end(); ++it) {
			packer_type::block_type &blk = it->second;
			printf("  %s [%d, %d] - [%d, %d]\n", it->first.c_str(), blk.fit->min_x(), blk.fit->min_y(), blk.fit->min_x() + blk.fit->width(), blk.fit->min_y() + blk.fit->height());
		}
	}
	if(failed.size()) {
		CONSOLE_COLOR(FOREGROUND_RED | FOREGROUND_GREEN);
		printf("Failed %d:\n", failed.size());
		for(auto it = failed.begin(); it != failed.end(); ++it) {
			packer_type::block_type &blk = it->second;
			printf("  %s\n", it->first.c_str());
		}
	}
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		printf("Cost time: %gs loading; %gs packing.\n", (float)load_time / 1000.0f, (float)pack_time / 1000.0f);
	}

	// Serializes.
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		std::string out_tex = outpath + ".png";
		result->save(out_tex.c_str());
		printf("Texture written: %s.\n", out_tex.c_str());
	}
	{
		CONSOLE_COLOR(FOREGROUND_INTENSITY);
		std::string out_meta = outpath + ".json";
		std::ofstream fs(out_meta);
		packer.write_meta(fs, packed, result, outpath.c_str());
		fs.close();
		printf("Meta data written: %s.\n", out_meta.c_str());
	}
}

static void _on_startup(void) {
	FreeImage_Initialise();
}

static void _on_exit(void) {
	FreeImage_DeInitialise();
}

int main(int argc, char* argv[]) {
	atexit(_on_exit);

	_on_startup();

	if(argc == 1)
		_show_tip();
	else if(argc >= 2)
		_process_parameters(argc, argv);

	return 0;
}
<|endoftext|>


<commit_before>76ad0dc5-2749-11e6-a21e-e0f84713e7b8<commit_msg>Put the thingie in the thingie<commit_after>76be8540-2749-11e6-9828-e0f84713e7b8<|endoftext|>