<commit_before>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-beta"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
//#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "85f303d"
#    define GIT_COMMIT_DATE "Sat, 15 Feb 2014 00:13:43 -1000"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Update version.cpp<commit_after>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Spots2");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-beta"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
//#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "85f303d"
#    define GIT_COMMIT_DATE "Sat, 15 Feb 2014 00:13:43 -1000"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before>static char *version_id =
	"@(#)Copyright (C) 2004-2017 H.Shirouzu	Version.cpp ver3.2.7.39";
/* ========================================================================
	Project  Name			: Fast/Force copy file and directory
	Module Name				: Version
	Create					: 2010-06-13(Sun)
	Update					: 2017-01-23(Mon)
	Copyright				: H.Shirouzu
	License					: GNU General Public License version 3
	Modify					: Mapaler 2015-09-23
	======================================================================== */

#include "tlib/tlib.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "version.h"

static char version_str[32];
static char copyright_str[128];
static char mender_str[128];
static char admin_str[32];

void SetVersionStr(BOOL is_admin, BOOL is_noui)
{
	sprintf(version_str, "%.20s", strstr(version_id, "ver"));

	if (is_admin) {
		strcpy(admin_str, " (Admin)");
	}
	if (is_noui) {
		strcpy(admin_str, " (NoUI)");
	}
}

const char *GetVersionStr()
{
	if (version_str[0] == 0) {
		SetVersionStr();
	}
	return	version_str;
}

const char *GetVerAdminStr()
{
	if (admin_str[0] == 0) {
		SetVersionStr();
	}
	return	admin_str;
}

const char *GetCopyrightStr(void)
{
	if (copyright_str[0] == 0) {
		char *s = strchr(version_id, 'C');
		char *e = strchr(version_id, '\t');
		if (s && e && s < e) {
			sprintf(copyright_str, "%.*s", int(e-s), s);
		}
	}
	return	copyright_str;
}

const char *GetMenderStr(void)
{
	if (mender_str[0] == 0) {
		sprintf(mender_str, "FastCopy-M branch By Mapaler");
	}
	return	mender_str;
}

<commit_msg>更改版本号<commit_after>static char *version_id =
	"@(#)Copyright (C) 2004-2017 H.Shirouzu	Version.cpp ver3.2.7.40";
/* ========================================================================
	Project  Name			: Fast/Force copy file and directory
	Module Name				: Version
	Create					: 2010-06-13(Sun)
	Update					: 2017-01-23(Mon)
	Copyright				: H.Shirouzu
	License					: GNU General Public License version 3
	Modify					: Mapaler 2015-09-23
	======================================================================== */

#include "tlib/tlib.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "version.h"

static char version_str[32];
static char copyright_str[128];
static char mender_str[128];
static char admin_str[32];

void SetVersionStr(BOOL is_admin, BOOL is_noui)
{
	sprintf(version_str, "%.20s", strstr(version_id, "ver"));

	if (is_admin) {
		strcpy(admin_str, " (Admin)");
	}
	if (is_noui) {
		strcpy(admin_str, " (NoUI)");
	}
}

const char *GetVersionStr()
{
	if (version_str[0] == 0) {
		SetVersionStr();
	}
	return	version_str;
}

const char *GetVerAdminStr()
{
	if (admin_str[0] == 0) {
		SetVersionStr();
	}
	return	admin_str;
}

const char *GetCopyrightStr(void)
{
	if (copyright_str[0] == 0) {
		char *s = strchr(version_id, 'C');
		char *e = strchr(version_id, '\t');
		if (s && e && s < e) {
			sprintf(copyright_str, "%.*s", int(e-s), s);
		}
	}
	return	copyright_str;
}

const char *GetMenderStr(void)
{
	if (mender_str[0] == 0) {
		sprintf(mender_str, "FastCopy-M branch By Mapaler");
	}
	return	mender_str;
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once
#include "bytes.hh"
#include "schema.hh"
#include "core/future.hh"
#include "database_fwd.hh"
#include "keys.hh"
#include "compound_compat.hh"

namespace sstables {

class key_view {
    bytes_view _bytes;
public:
    key_view(bytes_view b) : _bytes(b) {}
    key_view() : _bytes() {}

    std::vector<bytes> explode(const schema& s) const {
        return composite_view(_bytes, s.partition_key_size() > 1).explode();
    }

    bool operator==(const key_view& k) const { return k._bytes == _bytes; }
    bool operator!=(const key_view& k) const { return !(k == *this); }

    bool empty() { return _bytes.empty(); }

    explicit operator bytes_view() const {
        return _bytes;
    }

    int tri_compare(key_view other) const {
        return compare_unsigned(_bytes, other._bytes);
    }

    int tri_compare(const schema& s, partition_key_view other) const {
        auto lf = other.legacy_form(s);
        return lexicographical_tri_compare(
            _bytes.begin(), _bytes.end(), lf.begin(), lf.end(),
            [] (uint8_t b1, uint8_t b2) { return (int)b1 - b2; });
    }
};

// Our internal representation differs slightly (in the way it serializes) from Origin.
// In order to be able to achieve read and write compatibility for sstables - so they can
// be imported and exported - we need to always convert a key to this representation.
class key {
    enum class kind {
        before_all_keys,
        regular,
        after_all_keys,
    };
    kind _kind;
    bytes _bytes;
private:
    static bool is_compound(const schema& s) {
        return s.partition_key_size() > 1;
    }
public:
    key(bytes&& b) : _kind(kind::regular), _bytes(std::move(b)) {}
    key(kind k) : _kind(k) {}
    static key from_bytes(bytes b) {
        return key(std::move(b));
    }
    template <typename RangeOfSerializedComponents>
    static key make_key(const schema& s, RangeOfSerializedComponents&& values) {
        return key(composite::serialize_value(std::forward<decltype(values)>(values), is_compound(s)));
    }
    static key from_deeply_exploded(const schema& s, const std::vector<data_value>& v) {
        return make_key(s, v);
    }
    static key from_exploded(const schema& s, std::vector<bytes>& v) {
        return make_key(s, v);
    }
    static key from_exploded(const schema& s, std::vector<bytes>&& v) {
        return make_key(s, std::move(v));
    }
    // Unfortunately, the _bytes field for the partition_key are not public. We can't move.
    static key from_partition_key(const schema& s, partition_key_view pk) {
        return make_key(s, pk);
    }
    partition_key to_partition_key(const schema& s) const {
        return partition_key::from_exploded(s, explode(s));
    }

    std::vector<bytes> explode(const schema& s) const {
        return composite_view(_bytes, is_compound(s)).explode();
    }

    int32_t tri_compare(key_view k) const {
        if (_kind == kind::before_all_keys) {
            return -1;
        }
        if (_kind == kind::after_all_keys) {
            return 1;
        }
        return key_view(_bytes).tri_compare(k);
    }
    operator key_view() const {
        return key_view(_bytes);
    }
    explicit operator bytes_view() const {
        return _bytes;
    }
    const bytes& get_bytes() const {
        return _bytes;
    }
    friend key minimum_key();
    friend key maximum_key();
};

inline key minimum_key() {
    return key(key::kind::before_all_keys);
};

inline key maximum_key() {
    return key(key::kind::after_all_keys);
};

}
<commit_msg>sstables/key: Make key::kind public<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once
#include "bytes.hh"
#include "schema.hh"
#include "core/future.hh"
#include "database_fwd.hh"
#include "keys.hh"
#include "compound_compat.hh"

namespace sstables {

class key_view {
    bytes_view _bytes;
public:
    key_view(bytes_view b) : _bytes(b) {}
    key_view() : _bytes() {}

    std::vector<bytes> explode(const schema& s) const {
        return composite_view(_bytes, s.partition_key_size() > 1).explode();
    }

    bool operator==(const key_view& k) const { return k._bytes == _bytes; }
    bool operator!=(const key_view& k) const { return !(k == *this); }

    bool empty() { return _bytes.empty(); }

    explicit operator bytes_view() const {
        return _bytes;
    }

    int tri_compare(key_view other) const {
        return compare_unsigned(_bytes, other._bytes);
    }

    int tri_compare(const schema& s, partition_key_view other) const {
        auto lf = other.legacy_form(s);
        return lexicographical_tri_compare(
            _bytes.begin(), _bytes.end(), lf.begin(), lf.end(),
            [] (uint8_t b1, uint8_t b2) { return (int)b1 - b2; });
    }
};

// Our internal representation differs slightly (in the way it serializes) from Origin.
// In order to be able to achieve read and write compatibility for sstables - so they can
// be imported and exported - we need to always convert a key to this representation.
class key {
public:
    enum class kind {
        before_all_keys,
        regular,
        after_all_keys,
    };
private:
    kind _kind;
    bytes _bytes;

    static bool is_compound(const schema& s) {
        return s.partition_key_size() > 1;
    }
public:
    key(bytes&& b) : _kind(kind::regular), _bytes(std::move(b)) {}
    key(kind k) : _kind(k) {}
    static key from_bytes(bytes b) {
        return key(std::move(b));
    }
    template <typename RangeOfSerializedComponents>
    static key make_key(const schema& s, RangeOfSerializedComponents&& values) {
        return key(composite::serialize_value(std::forward<decltype(values)>(values), is_compound(s)));
    }
    static key from_deeply_exploded(const schema& s, const std::vector<data_value>& v) {
        return make_key(s, v);
    }
    static key from_exploded(const schema& s, std::vector<bytes>& v) {
        return make_key(s, v);
    }
    static key from_exploded(const schema& s, std::vector<bytes>&& v) {
        return make_key(s, std::move(v));
    }
    // Unfortunately, the _bytes field for the partition_key are not public. We can't move.
    static key from_partition_key(const schema& s, partition_key_view pk) {
        return make_key(s, pk);
    }
    partition_key to_partition_key(const schema& s) const {
        return partition_key::from_exploded(s, explode(s));
    }

    std::vector<bytes> explode(const schema& s) const {
        return composite_view(_bytes, is_compound(s)).explode();
    }

    int32_t tri_compare(key_view k) const {
        if (_kind == kind::before_all_keys) {
            return -1;
        }
        if (_kind == kind::after_all_keys) {
            return 1;
        }
        return key_view(_bytes).tri_compare(k);
    }
    operator key_view() const {
        return key_view(_bytes);
    }
    explicit operator bytes_view() const {
        return _bytes;
    }
    const bytes& get_bytes() const {
        return _bytes;
    }
    friend key minimum_key();
    friend key maximum_key();
};

inline key minimum_key() {
    return key(key::kind::before_all_keys);
};

inline key maximum_key() {
    return key(key::kind::after_all_keys);
};

}
<|endoftext|>


<commit_before><commit_msg>[otbn] Inline EXPECT_EQ calls.<commit_after><|endoftext|>


<commit_before>/*
 *          Copyright Andrey Semashev 2007 - 2014.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   static_type_dispatcher.hpp
 * \author Andrey Semashev
 * \date   15.04.2007
 *
 * The header contains implementation of a compile-time type dispatcher.
 */

#ifndef BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
#define BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_

#include <cstddef>
#include <utility>
#include <iterator>
#include <algorithm>
#include <boost/array.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/visible_type.hpp>
#include <boost/log/utility/once_block.hpp>
#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
#include <boost/log/detail/header.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace aux {

//! Ordering predicate for type dispatching map
struct dispatching_map_order
{
    typedef bool result_type;
    typedef std::pair< type_info_wrapper, void* > first_argument_type, second_argument_type;
    result_type operator() (first_argument_type const& left, second_argument_type const& right) const
    {
        return (left.first < right.first);
    }
};

//! Dispatching map filler
template< typename VisitorT >
struct dispatching_map_initializer
{
    template< typename IteratorT >
    static BOOST_FORCEINLINE void init(IteratorT*, IteratorT*, std::pair< type_info_wrapper, void* >*)
    {
    }

    template< typename BeginIteratorT, typename EndIteratorT >
    static BOOST_FORCEINLINE void init(BeginIteratorT*, EndIteratorT* end, std::pair< type_info_wrapper, void* >* p)
    {
        typedef typename mpl::deref< BeginIteratorT >::type type;
        do_init(static_cast< visible_type< type >* >(0), p);

        typedef typename mpl::next< BeginIteratorT >::type next_iterator_type;
        init(static_cast< next_iterator_type* >(0), end, p + 1);
    }

private:
    template< typename T >
    static BOOST_FORCEINLINE void do_init(visible_type< T >*, std::pair< type_info_wrapper, void* >* p)
    {
        p->first = typeid(visible_type< T >);

        typedef void (*trampoline_t)(void*, T const&);
        BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
        union
        {
            void* as_pvoid;
            trampoline_t as_trampoline;
        }
        caster;
        caster.as_trampoline = &type_dispatcher::callback_base::trampoline< VisitorT, T >;
        p->second = caster.as_pvoid;
    }
};

//! A dispatcher that supports a sequence of types
template< typename TypeSequenceT >
class type_sequence_dispatcher :
    public type_dispatcher
{
public:
    //! Type sequence of the supported types
    typedef TypeSequenceT supported_types;

private:
    //! The dispatching map
    typedef array<
        std::pair< type_info_wrapper, void* >,
        mpl::size< supported_types >::value
    > dispatching_map;

private:
    //! Pointer to the receiver function
    void* m_pVisitor;
    //! Pointer to the dispatching map
    dispatching_map const& m_DispatchingMap;

public:
    /*!
     * Constructor. Initializes the dispatcher internals.
     */
    template< typename VisitorT >
    explicit type_sequence_dispatcher(VisitorT& visitor) :
        type_dispatcher(&type_sequence_dispatcher< supported_types >::get_callback),
        m_pVisitor((void*)boost::addressof(visitor)),
        m_DispatchingMap(get_dispatching_map< VisitorT >())
    {
    }

private:
    //! The get_callback method implementation
    static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
    {
        type_sequence_dispatcher* const self = static_cast< type_sequence_dispatcher* >(p);
        type_info_wrapper wrapper(type);
        typename dispatching_map::value_type const* begin = &*self->m_DispatchingMap.begin();
        typename dispatching_map::value_type const* end = begin + dispatching_map::static_size;
        typename dispatching_map::value_type const* it =
            std::lower_bound(
                begin,
                end,
                std::make_pair(wrapper, (void*)0),
                dispatching_map_order()
            );

        if (it != end && it->first == wrapper)
            return callback_base(self->m_pVisitor, it->second);
        else
            return callback_base();
    }

    //! The method returns the dispatching map instance
    template< typename VisitorT >
    static dispatching_map const& get_dispatching_map()
    {
        static const dispatching_map* pinstance = NULL;

        BOOST_LOG_ONCE_BLOCK()
        {
            static dispatching_map instance;
            typename dispatching_map::value_type* p = &*instance.begin();

            typedef typename mpl::begin< supported_types >::type begin_iterator_type;
            typedef typename mpl::end< supported_types >::type end_iterator_type;
            typedef dispatching_map_initializer< VisitorT > initializer;
            initializer::init(static_cast< begin_iterator_type* >(0), static_cast< end_iterator_type* >(0), p);

            std::sort(instance.begin(), instance.end(), dispatching_map_order());

            pinstance = &instance;
        }

        return *pinstance;
    }

    //  Copying and assignment closed
    BOOST_DELETED_FUNCTION(type_sequence_dispatcher(type_sequence_dispatcher const&))
    BOOST_DELETED_FUNCTION(type_sequence_dispatcher& operator= (type_sequence_dispatcher const&))
};

//! A simple dispatcher that only supports one type
template< typename T >
class single_type_dispatcher :
    public type_dispatcher
{
private:
    //! A callback for the supported type
    callback_base m_Callback;

public:
    //! Constructor
    template< typename VisitorT >
    explicit single_type_dispatcher(VisitorT& visitor) :
        type_dispatcher(&single_type_dispatcher< T >::get_callback),
        m_Callback(
            (void*)boost::addressof(visitor),
            &callback_base::trampoline< VisitorT, T >
        )
    {
    }
    //! The get_callback method implementation
    static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
    {
        if (type == typeid(visible_type< T >))
        {
            single_type_dispatcher* const self = static_cast< single_type_dispatcher* >(p);
            return self->m_Callback;
        }
        else
            return callback_base();
    }

    //  Copying and assignment closed
    BOOST_DELETED_FUNCTION(single_type_dispatcher(single_type_dispatcher const&))
    BOOST_DELETED_FUNCTION(single_type_dispatcher& operator= (single_type_dispatcher const&))
};

} // namespace aux

/*!
 * \brief A static type dispatcher class
 *
 * The type dispatcher can be used to pass objects of arbitrary types from one
 * component to another. With regard to the library, the type dispatcher
 * can be used to extract attribute values.
 *
 * Static type dispatchers allow to specify one or several supported types at compile
 * time.
 */
template< typename T >
class static_type_dispatcher
#ifndef BOOST_LOG_DOXYGEN_PASS
    :
    public mpl::if_<
        mpl::is_sequence< T >,
        boost::log::aux::type_sequence_dispatcher< T >,
        boost::log::aux::single_type_dispatcher< T >
    >::type
#endif
{
private:
    //! Base type
    typedef typename mpl::if_<
        mpl::is_sequence< T >,
        boost::log::aux::type_sequence_dispatcher< T >,
        boost::log::aux::single_type_dispatcher< T >
    >::type base_type;

public:
    /*!
     * Constructor. Initializes the dispatcher internals.
     */
    template< typename ReceiverT >
    explicit static_type_dispatcher(ReceiverT& receiver) :
        base_type(receiver)
    {
    }

    //  Copying and assignment prohibited
    BOOST_DELETED_FUNCTION(static_type_dispatcher(static_type_dispatcher const&))
    BOOST_DELETED_FUNCTION(static_type_dispatcher& operator= (static_type_dispatcher const&))
};

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
<commit_msg>Optimizations for code size and possibly compile times.<commit_after>/*
 *          Copyright Andrey Semashev 2007 - 2014.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
/*!
 * \file   static_type_dispatcher.hpp
 * \author Andrey Semashev
 * \date   15.04.2007
 *
 * The header contains implementation of a compile-time type dispatcher.
 */

#ifndef BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
#define BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_

#include <cstddef>
#include <utility>
#include <iterator>
#include <algorithm>
#include <boost/array.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/log/detail/config.hpp>
#include <boost/log/detail/visible_type.hpp>
#include <boost/log/utility/once_block.hpp>
#include <boost/log/utility/type_info_wrapper.hpp>
#include <boost/log/utility/type_dispatch/type_dispatcher.hpp>
#include <boost/log/detail/header.hpp>

#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

namespace boost {

BOOST_LOG_OPEN_NAMESPACE

namespace aux {

//! Ordering predicate for type dispatching map
struct dispatching_map_order
{
    typedef bool result_type;
    typedef std::pair< type_info_wrapper, void* > first_argument_type, second_argument_type;
    result_type operator() (first_argument_type const& left, second_argument_type const& right) const
    {
        return (left.first < right.first);
    }
};

//! Dispatching map filler
template< typename VisitorT >
struct dispatching_map_initializer
{
    template< typename IteratorT >
    static BOOST_FORCEINLINE void init(IteratorT*, IteratorT*, std::pair< type_info_wrapper, void* >*)
    {
    }

    template< typename BeginIteratorT, typename EndIteratorT >
    static BOOST_FORCEINLINE void init(BeginIteratorT*, EndIteratorT* end, std::pair< type_info_wrapper, void* >* p)
    {
        typedef typename mpl::deref< BeginIteratorT >::type type;
        do_init(static_cast< visible_type< type >* >(0), p);

        typedef typename mpl::next< BeginIteratorT >::type next_iterator_type;
        init(static_cast< next_iterator_type* >(0), end, p + 1);
    }

private:
    template< typename T >
    static BOOST_FORCEINLINE void do_init(visible_type< T >*, std::pair< type_info_wrapper, void* >* p)
    {
        p->first = typeid(visible_type< T >);

        typedef void (*trampoline_t)(void*, T const&);
        BOOST_STATIC_ASSERT_MSG(sizeof(trampoline_t) == sizeof(void*), "Boost.Log: Unsupported platform, the size of a function pointer differs from the size of a pointer");
        union
        {
            void* as_pvoid;
            trampoline_t as_trampoline;
        }
        caster;
        caster.as_trampoline = &type_dispatcher::callback_base::trampoline< VisitorT, T >;
        p->second = caster.as_pvoid;
    }
};

//! A base class for a dispatcher that supports a sequence of types
class type_sequence_dispatcher_base :
    public type_dispatcher
{
private:
    //! Dispatching map element type
    typedef std::pair< type_info_wrapper, void* > dispatching_map_element_type;

private:
    //! Dispatching map
    const dispatching_map_element_type* m_dispatching_map_begin, *m_dispatching_map_end;
    //! Pointer to the receiver function
    void* m_visitor;

protected:
    //! Initializing constructor
    template< typename VisitorT, std::size_t N >
    type_sequence_dispatcher_base(array< dispatching_map_element_type, N > const& disp_map, VisitorT& visitor) :
        type_dispatcher(&type_sequence_dispatcher_base::get_callback),
        m_dispatching_map_begin(disp_map.begin()),
        m_dispatching_map_end(disp_map.end()),
        m_visitor((void*)boost::addressof(visitor))
    {
    }

private:
    //! The get_callback method implementation
    static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
    {
        type_sequence_dispatcher_base* const self = static_cast< type_sequence_dispatcher_base* >(p);
        type_info_wrapper wrapper(type);
        const dispatching_map_element_type* begin = self->m_dispatching_map_begin;
        const dispatching_map_element_type* end = self->m_dispatching_map_end;
        const dispatching_map_element_type* it =
            std::lower_bound(
                begin,
                end,
                dispatching_map_element_type(wrapper, (void*)0),
                dispatching_map_order()
            );

        if (it != end && it->first == wrapper)
            return callback_base(self->m_visitor, it->second);
        else
            return callback_base();
    }

    //  Copying and assignment closed
    BOOST_DELETED_FUNCTION(type_sequence_dispatcher_base(type_sequence_dispatcher_base const&))
    BOOST_DELETED_FUNCTION(type_sequence_dispatcher_base& operator= (type_sequence_dispatcher_base const&))
};

//! A dispatcher that supports a sequence of types
template< typename TypeSequenceT >
class type_sequence_dispatcher :
    public type_sequence_dispatcher_base
{
public:
    //! Type sequence of the supported types
    typedef TypeSequenceT supported_types;

private:
    //! The dispatching map
    typedef array<
        std::pair< type_info_wrapper, void* >,
        mpl::size< supported_types >::value
    > dispatching_map;

public:
    /*!
     * Constructor. Initializes the dispatcher internals.
     */
    template< typename VisitorT >
    explicit type_sequence_dispatcher(VisitorT& visitor) :
        type_sequence_dispatcher_base(get_dispatching_map< VisitorT >(), visitor)
    {
    }

private:
    //! The method returns the dispatching map instance
    template< typename VisitorT >
    static dispatching_map const& get_dispatching_map()
    {
        static const dispatching_map* pinstance = NULL;

        BOOST_LOG_ONCE_BLOCK()
        {
            static dispatching_map instance;
            typename dispatching_map::value_type* p = &*instance.begin();

            typedef typename mpl::begin< supported_types >::type begin_iterator_type;
            typedef typename mpl::end< supported_types >::type end_iterator_type;
            typedef dispatching_map_initializer< VisitorT > initializer;
            initializer::init(static_cast< begin_iterator_type* >(0), static_cast< end_iterator_type* >(0), p);

            std::sort(instance.begin(), instance.end(), dispatching_map_order());

            pinstance = &instance;
        }

        return *pinstance;
    }

    //  Copying and assignment closed
    BOOST_DELETED_FUNCTION(type_sequence_dispatcher(type_sequence_dispatcher const&))
    BOOST_DELETED_FUNCTION(type_sequence_dispatcher& operator= (type_sequence_dispatcher const&))
};

//! A base class for a single-type dispatcher
class single_type_dispatcher_base :
    public type_dispatcher
{
private:
    //! The type to match against
    std::type_info const& m_type;
    //! A callback for the supported type
    callback_base m_callback;

protected:
    //! Initializing constructor
    single_type_dispatcher_base(std::type_info const& type, callback_base const& callback) :
        type_dispatcher(&single_type_dispatcher_base::get_callback),
        m_type(type),
        m_callback(callback)
    {
    }

private:
    //! The get_callback method implementation
    static callback_base get_callback(type_dispatcher* p, std::type_info const& type)
    {
        single_type_dispatcher_base* const self = static_cast< single_type_dispatcher_base* >(p);
        if (type == self->m_type)
            return self->m_callback;
        else
            return callback_base();
    }

    //  Copying and assignment closed
    BOOST_DELETED_FUNCTION(single_type_dispatcher_base(single_type_dispatcher_base const&))
    BOOST_DELETED_FUNCTION(single_type_dispatcher_base& operator= (single_type_dispatcher_base const&))
};

//! A simple dispatcher that only supports one type
template< typename T >
class single_type_dispatcher :
    public single_type_dispatcher_base
{
public:
    //! Constructor
    template< typename VisitorT >
    explicit single_type_dispatcher(VisitorT& visitor) :
        single_type_dispatcher_base(typeid(visible_type< T >), callback_base((void*)boost::addressof(visitor), &callback_base::trampoline< VisitorT, T >))
    {
    }

    //  Copying and assignment closed
    BOOST_DELETED_FUNCTION(single_type_dispatcher(single_type_dispatcher const&))
    BOOST_DELETED_FUNCTION(single_type_dispatcher& operator= (single_type_dispatcher const&))
};

} // namespace aux

/*!
 * \brief A static type dispatcher class
 *
 * The type dispatcher can be used to pass objects of arbitrary types from one
 * component to another. With regard to the library, the type dispatcher
 * can be used to extract attribute values.
 *
 * Static type dispatchers allow to specify one or several supported types at compile
 * time.
 */
template< typename T >
class static_type_dispatcher
#ifndef BOOST_LOG_DOXYGEN_PASS
    :
    public mpl::if_<
        mpl::is_sequence< T >,
        boost::log::aux::type_sequence_dispatcher< T >,
        boost::log::aux::single_type_dispatcher< T >
    >::type
#endif
{
private:
    //! Base type
    typedef typename mpl::if_<
        mpl::is_sequence< T >,
        boost::log::aux::type_sequence_dispatcher< T >,
        boost::log::aux::single_type_dispatcher< T >
    >::type base_type;

public:
    /*!
     * Constructor. Initializes the dispatcher internals.
     */
    template< typename ReceiverT >
    explicit static_type_dispatcher(ReceiverT& receiver) :
        base_type(receiver)
    {
    }

    //  Copying and assignment prohibited
    BOOST_DELETED_FUNCTION(static_type_dispatcher(static_type_dispatcher const&))
    BOOST_DELETED_FUNCTION(static_type_dispatcher& operator= (static_type_dispatcher const&))
};

BOOST_LOG_CLOSE_NAMESPACE // namespace log

} // namespace boost

#include <boost/log/detail/footer.hpp>

#endif // BOOST_LOG_STATIC_TYPE_DISPATCHER_HPP_INCLUDED_
<|endoftext|>


<commit_before><commit_msg>exit loop in case i2c device not responding<commit_after><|endoftext|>


<commit_before>#include "CppRandom.hpp"

namespace Dissent {
namespace Crypto {
  CppRandom::CppRandom(const QByteArray &seed, uint index)
  {
    if(seed.isEmpty()) {
      _rng.reset(new CryptoPP::AutoSeededX917RNG<CryptoPP::AES>());
      return;
    }

    QByteArray seed_tmp(seed);
    seed_tmp.resize(CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::BlockTransformation *bt = new CryptoPP::AES::Encryption(
        reinterpret_cast<byte *>(seed_tmp.data()), seed_tmp.size());

    QByteArray zero(CryptoPP::AES::DEFAULT_KEYLENGTH, 0);
    const byte *zerob = reinterpret_cast<const byte *>(zero.data());
    _rng.reset(new CryptoPP::X917RNG(bt, zerob, zerob));

    if(index) {
      MoveRngPosition(index);
    }
  }

  int CppRandom::GetInt(int min, int max)
  {
    if(min == max) {
      return min;
    }
    IncrementByteCount(4);
    return _rng->GenerateWord32(min, max - 1);
  }

  void CppRandom::GenerateBlock(QByteArray &data)
  {
    _rng->GenerateBlock(reinterpret_cast<byte *>(data.data()), data.size());
    IncrementByteCount(data.size());
  }
}
}
<commit_msg>[Crypto] Application crashes when we run out of descriptors, so we make it clear why in CppRandom<commit_after>#include "CppRandom.hpp"

namespace Dissent {
namespace Crypto {
  CppRandom::CppRandom(const QByteArray &seed, uint index)
  {
    if(seed.isEmpty()) {
      try {
        _rng.reset(new CryptoPP::AutoSeededX917RNG<CryptoPP::AES>());
      } catch (CryptoPP::OS_RNG_Err &ex) {
        qFatal("Ran out of file descriptors, when creating a CppRandom.");
      }
      return;
    }

    QByteArray seed_tmp(seed);
    seed_tmp.resize(CryptoPP::AES::DEFAULT_KEYLENGTH);
    CryptoPP::BlockTransformation *bt = new CryptoPP::AES::Encryption(
        reinterpret_cast<byte *>(seed_tmp.data()), seed_tmp.size());

    QByteArray zero(CryptoPP::AES::DEFAULT_KEYLENGTH, 0);
    const byte *zerob = reinterpret_cast<const byte *>(zero.data());
    _rng.reset(new CryptoPP::X917RNG(bt, zerob, zerob));

    if(index) {
      MoveRngPosition(index);
    }
  }

  int CppRandom::GetInt(int min, int max)
  {
    if(min == max) {
      return min;
    }
    IncrementByteCount(4);
    return _rng->GenerateWord32(min, max - 1);
  }

  void CppRandom::GenerateBlock(QByteArray &data)
  {
    _rng->GenerateBlock(reinterpret_cast<byte *>(data.data()), data.size());
    IncrementByteCount(data.size());
  }
}
}
<|endoftext|>


<commit_before>// Scintilla source code edit control
/** @file DocumentAccessor.cxx
 ** Rapid easy access to contents of a Scintilla.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>

#include "Platform.h"

#include "PropSet.h"
#include "SVector.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "CellBuffer.h"
#include "Scintilla.h"
#include "Document.h"

DocumentAccessor::~DocumentAccessor() {
}

bool DocumentAccessor::InternalIsLeadByte(char ch) {
	if (SC_CP_UTF8 == codePage)
		// For lexing, all characters >= 0x80 are treated the
		// same so none is considered a lead byte.
		return false;
	else
		return Platform::IsDBCSLeadByte(codePage, ch);
}

void DocumentAccessor::Fill(int position) {
	if (lenDoc == -1)
		lenDoc = pdoc->Length();
	startPos = position - slopSize;
	if (startPos + bufferSize > lenDoc)
		startPos = lenDoc - bufferSize;
	if (startPos < 0)
		startPos = 0;
	endPos = startPos + bufferSize;
	if (endPos > lenDoc)
		endPos = lenDoc;

	pdoc->GetCharRange(buf, startPos, endPos-startPos);
	buf[endPos-startPos] = '\0';
}

bool DocumentAccessor::Match(int pos, const char *s) {
	for (int i=0; *s; i++) {
		if (*s != SafeGetCharAt(pos+i))
			return false;
		s++;
	}
	return true;
}

char DocumentAccessor::StyleAt(int position) {
	return pdoc->StyleAt(position);
}

int DocumentAccessor::GetLine(int position) {
	return pdoc->LineFromPosition(position);
}

int DocumentAccessor::LineStart(int line) {
	return pdoc->LineStart(line);
}

int DocumentAccessor::LevelAt(int line) {
	return pdoc->GetLevel(line);
}

int DocumentAccessor::Length() {
	if (lenDoc == -1)
		lenDoc = pdoc->Length();
	return lenDoc;
}

int DocumentAccessor::GetLineState(int line) {
	return pdoc->GetLineState(line);
}

int DocumentAccessor::SetLineState(int line, int state) {
	return pdoc->SetLineState(line, state);
}

void DocumentAccessor::StartAt(unsigned int start, char chMask) {
	pdoc->StartStyling(start, chMask);
	startPosStyling = start;
}

void DocumentAccessor::StartSegment(unsigned int pos) {
	startSeg = pos;
}

void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {
	// Only perform styling if non empty range
	if (pos != startSeg - 1) {
		if (pos < startSeg) {
			Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos);
		}

		if (validLen + (pos - startSeg + 1) >= bufferSize)
			Flush();
		if (validLen + (pos - startSeg + 1) >= bufferSize) {
			// Too big for buffer so send directly
			pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
		} else {
			if (chAttr != chWhile)
				chFlags = 0;
			chAttr |= chFlags;
			for (unsigned int i = startSeg; i <= pos; i++) {
				PLATFORM_ASSERT((startPosStyling + validLen) < Length());
				styleBuf[validLen++] = static_cast<char>(chAttr);
			}
		}
	}
	startSeg = pos+1;
}

void DocumentAccessor::SetLevel(int line, int level) {
	pdoc->SetLevel(line, level);
}

void DocumentAccessor::Flush() {
	startPos = extremePosition;
	lenDoc = -1;
	if (validLen > 0) {
		pdoc->SetStyles(validLen, styleBuf);
		validLen = 0;
		startPosStyling += validLen;
	}
}

int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
	int end = Length();
	int spaceFlags = 0;

	// Determines the indentation level of the current line and also checks for consistent
	// indentation compared to the previous line.
	// Indentation is judged consistent when the indentation whitespace of each line lines
	// the same or the indentation of one line is a prefix of the other.

	int pos = LineStart(line);
	char ch = (*this)[pos];
	int indent = 0;
	bool inPrevPrefix = line > 0;
	int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
	while ((ch == ' ' || ch == '\t') && (pos < end)) {
		if (inPrevPrefix) {
			char chPrev = (*this)[posPrev++];
			if (chPrev == ' ' || chPrev == '\t') {
				if (chPrev != ch)
					spaceFlags |= wsInconsistent;
			} else {
				inPrevPrefix = false;
			}
		}
		if (ch == ' ') {
			spaceFlags |= wsSpace;
			indent++;
		} else {	// Tab
			spaceFlags |= wsTab;
			if (spaceFlags & wsSpace)
				spaceFlags |= wsSpaceTab;
			indent = (indent / 8 + 1) * 8;
		}
		ch = (*this)[++pos];
	}

	*flags = spaceFlags;
	indent += SC_FOLDLEVELBASE;
	// if completely empty line or the start of a comment...
	if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
		(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
		return indent | SC_FOLDLEVELWHITEFLAG;
	else
		return indent;
}

<commit_msg>Fixed bug where assertions may not have been appearing when they should.<commit_after>// Scintilla source code edit control
/** @file DocumentAccessor.cxx
 ** Rapid easy access to contents of a Scintilla.
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>

#include "Platform.h"

#include "PropSet.h"
#include "SVector.h"
#include "Accessor.h"
#include "DocumentAccessor.h"
#include "CellBuffer.h"
#include "Scintilla.h"
#include "Document.h"

DocumentAccessor::~DocumentAccessor() {
}

bool DocumentAccessor::InternalIsLeadByte(char ch) {
	if (SC_CP_UTF8 == codePage)
		// For lexing, all characters >= 0x80 are treated the
		// same so none is considered a lead byte.
		return false;
	else
		return Platform::IsDBCSLeadByte(codePage, ch);
}

void DocumentAccessor::Fill(int position) {
	if (lenDoc == -1)
		lenDoc = pdoc->Length();
	startPos = position - slopSize;
	if (startPos + bufferSize > lenDoc)
		startPos = lenDoc - bufferSize;
	if (startPos < 0)
		startPos = 0;
	endPos = startPos + bufferSize;
	if (endPos > lenDoc)
		endPos = lenDoc;

	pdoc->GetCharRange(buf, startPos, endPos-startPos);
	buf[endPos-startPos] = '\0';
}

bool DocumentAccessor::Match(int pos, const char *s) {
	for (int i=0; *s; i++) {
		if (*s != SafeGetCharAt(pos+i))
			return false;
		s++;
	}
	return true;
}

char DocumentAccessor::StyleAt(int position) {
	return pdoc->StyleAt(position);
}

int DocumentAccessor::GetLine(int position) {
	return pdoc->LineFromPosition(position);
}

int DocumentAccessor::LineStart(int line) {
	return pdoc->LineStart(line);
}

int DocumentAccessor::LevelAt(int line) {
	return pdoc->GetLevel(line);
}

int DocumentAccessor::Length() {
	if (lenDoc == -1)
		lenDoc = pdoc->Length();
	return lenDoc;
}

int DocumentAccessor::GetLineState(int line) {
	return pdoc->GetLineState(line);
}

int DocumentAccessor::SetLineState(int line, int state) {
	return pdoc->SetLineState(line, state);
}

void DocumentAccessor::StartAt(unsigned int start, char chMask) {
	pdoc->StartStyling(start, chMask);
	startPosStyling = start;
}

void DocumentAccessor::StartSegment(unsigned int pos) {
	startSeg = pos;
}

void DocumentAccessor::ColourTo(unsigned int pos, int chAttr) {
	// Only perform styling if non empty range
	if (pos != startSeg - 1) {
		if (pos < startSeg) {
			Platform::DebugPrintf("Bad colour positions %d - %d\n", startSeg, pos);
		}

		if (validLen + (pos - startSeg + 1) >= bufferSize)
			Flush();
		if (validLen + (pos - startSeg + 1) >= bufferSize) {
			// Too big for buffer so send directly
			pdoc->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
		} else {
			if (chAttr != chWhile)
				chFlags = 0;
			chAttr |= chFlags;
			for (unsigned int i = startSeg; i <= pos; i++) {
				PLATFORM_ASSERT((startPosStyling + validLen) < Length());
				styleBuf[validLen++] = static_cast<char>(chAttr);
			}
		}
	}
	startSeg = pos+1;
}

void DocumentAccessor::SetLevel(int line, int level) {
	pdoc->SetLevel(line, level);
}

void DocumentAccessor::Flush() {
	startPos = extremePosition;
	lenDoc = -1;
	if (validLen > 0) {
		pdoc->SetStyles(validLen, styleBuf);
		startPosStyling += validLen;
		validLen = 0;
	}
}

int DocumentAccessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
	int end = Length();
	int spaceFlags = 0;

	// Determines the indentation level of the current line and also checks for consistent
	// indentation compared to the previous line.
	// Indentation is judged consistent when the indentation whitespace of each line lines
	// the same or the indentation of one line is a prefix of the other.

	int pos = LineStart(line);
	char ch = (*this)[pos];
	int indent = 0;
	bool inPrevPrefix = line > 0;
	int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
	while ((ch == ' ' || ch == '\t') && (pos < end)) {
		if (inPrevPrefix) {
			char chPrev = (*this)[posPrev++];
			if (chPrev == ' ' || chPrev == '\t') {
				if (chPrev != ch)
					spaceFlags |= wsInconsistent;
			} else {
				inPrevPrefix = false;
			}
		}
		if (ch == ' ') {
			spaceFlags |= wsSpace;
			indent++;
		} else {	// Tab
			spaceFlags |= wsTab;
			if (spaceFlags & wsSpace)
				spaceFlags |= wsSpaceTab;
			indent = (indent / 8 + 1) * 8;
		}
		ch = (*this)[++pos];
	}

	*flags = spaceFlags;
	indent += SC_FOLDLEVELBASE;
	// if completely empty line or the start of a comment...
	if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
		(pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)) )
		return indent | SC_FOLDLEVELWHITEFLAG;
	else
		return indent;
}

<|endoftext|>


<commit_before>#include "CompCamera.h"
#include "CompMesh.h"
#include "CompTransform.h"
#include "MathGeoLib.h"
#include "Application.h"
#include "Scene.h"
#include "ModuleFS.h"
#include "ModuleRenderer3D.h"
#include "GameObject.h"

#include "SDL\include\SDL_opengl.h"
#include <math.h>

CompCamera::CompCamera(Comp_Type t, GameObject* parent) : Component(t, parent)
{
	nameComponent = "Camera";
	//uid = App->random->Int();
	/* Set camera vars*/
	width = 16;
	height = 9;
	aspect_ratio = width / height; // We set aspect ratio 16:9 by now

	near_plane = 0.2;
	far_plane = 1000;
	vertical_fov = 60; /* In degrees */

	/* Set frustum vars */
	frustum.type = PerspectiveFrustum;
	frustum.pos.Set(0, 0, 0);
	frustum.front.Set(0, 0, 1);
	frustum.up.Set(0, 1, 0);

	frustum.nearPlaneDistance = near_plane;
	frustum.farPlaneDistance = far_plane;
	frustum.verticalFov = vertical_fov * DEGTORAD;
	frustum.horizontalFov = Atan(aspect_ratio*Tan(frustum.verticalFov / 2)) * 2;
}

CompCamera::~CompCamera()
{
}

void CompCamera::preUpdate(float dt)
{
	if (culling)
	{
		// Iterate All GameObjects and apply culling
		DoCulling();
	}
}

void CompCamera::Update(float dt)
{
	UpdateFrustum();
}

void CompCamera::UpdateFrustum()
{
	const CompTransform* transform = parent->GetComponentTransform();

	float4x4 trans = transform->GetGlobalTransform();

	frustum.pos = trans.TranslatePart();
	frustum.front = trans.WorldZ();
	frustum.up = frustum.front.Cross(-frustum.WorldRight());
}

void CompCamera::Draw()
{
	// if(parent->selected == true)
	DebugDraw();
}

void CompCamera::DebugDraw()
{
	glBindTexture(GL_TEXTURE_2D, 0);
	glBegin(GL_LINES);
	glLineWidth(3.0f);
	glColor4f(0.25f, 1.0f, 0.0f, 1.0f);

	for (uint i = 0; i < 12; i++)
	{
		glVertex3f(frustum.Edge(i).a.x, frustum.Edge(i).a.y, frustum.Edge(i).a.z);
		glVertex3f(frustum.Edge(i).b.x, frustum.Edge(i).b.y, frustum.Edge(i).b.z);
	}

	glEnd();
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

void CompCamera::ShowOptions()
{
	//ImGui::MenuItem("CREATE", NULL, false, false);
	if (ImGui::MenuItem("Reset"))
	{
		// Not implmented yet.
	}
	ImGui::Separator();
	if (ImGui::MenuItem("Move to Front", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Move to Back", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Remove Component"))
	{
		toDelete = true;
	}
	if (ImGui::MenuItem("Move Up", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Move Down", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Copy Component"))
	{
		// Component* Copy = this;
	}
	if (ImGui::MenuItem("Paste Component", NULL, false, false))
	{
		//parent->AddComponent(App->scene->copyComponent->GetType())
		// Create contructor Component Copy or add funtion to add info
	}
}

void CompCamera::ShowInspectorInfo()
{
	// Reset Values Button -------------------------------------------
	ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3, 0));
	ImGui::SameLine(ImGui::GetWindowWidth() - 26);
	if (ImGui::ImageButton((ImTextureID*)App->scene->icon_options_transform, ImVec2(13, 13), ImVec2(-1, 1), ImVec2(0, 0)))
	{
		// Open Options
	}
	ImGui::PopStyleVar();

	if (ImGui::Checkbox("Main Camera", &is_main))
	{
		SetMain(is_main);
	}

	if (ImGui::Checkbox("Culling", &culling))
	{
		if (!culling)
		{
			UnCull();
		}
	}

	ImGui::PushItemWidth(80);
	if (ImGui::DragFloat("Near Plane", &near_plane, 0.5f, 0.01f, far_plane - 0.01f))
	{
		SetNear(near_plane);
	}
	if (ImGui::DragFloat("Far Plane", &far_plane, 0.5f, near_plane + 0.01f, 1000.0f))
	{
		SetFar(far_plane);
	}
	if (ImGui::SliderFloat("FOV", &vertical_fov, 1, 179))
	{
		SetFov(vertical_fov);
	}

	ImGui::PopItemWidth();
	ImGui::TreePop();
}

void CompCamera::DoCulling()
{
	// First check culling with static objects (optimized with quadtree)
	CullStaticObjects();

	// Then check dynamic objects
	CullDynamicObjects();
}

void CompCamera::CullStaticObjects()
{
	// Set all static objects invisible first
	for (uint i = 0; i < App->scene->static_objects.size(); i++)
	{
		App->scene->static_objects[i]->SetVisible(false);
	}

	candidates_to_cull.clear();
	// Get all static objects that are inside the frustum (accelerated with quadtree)
	App->scene->quadtree.CollectCandidates(candidates_to_cull, frustum);

	// Set visible only these static objects
	for (uint i = 0; i < candidates_to_cull.size(); i++)
	{
		candidates_to_cull[i]->SetVisible(true);
	}
}

void CompCamera::CullDynamicObjects()
{
	AABB* box = nullptr;
	for (uint i = 0; i < App->scene->gameobjects.size(); i++)
	{
		if (App->scene->gameobjects[i]->isActive() && App->scene->gameobjects[i] != parent) // Don't cull itself
		{
			if (!App->scene->gameobjects[i]->isStatic())
			{
				// Check its bounding box
				box = &App->scene->gameobjects[i]->box_fixed;
				if (box != nullptr)
				{
					// We set visible varialbe True / False to know if the GameObject will be drawn(or not) in renderer PostUpdate
					if (ContainsAABox(*box) == CULL_OUT)
					{
						App->scene->gameobjects[i]->SetVisible(false);
					}
					else
					{
						App->scene->gameobjects[i]->SetVisible(true);
					}
				}
			}
		}
	}
}

void CompCamera::UnCull()
{
	for (uint i = 0; i < App->scene->gameobjects.size(); i++)
	{
		if (App->scene->gameobjects[i]->isActive())
		{
			App->scene->gameobjects[i]->SetVisible(true);
		}
	}
}

void CompCamera::LookAt(const float3& position)
{
	float3 direction = position - frustum.pos;
	float3x3 matrix = float3x3::LookAt(frustum.front, direction.Normalized(), frustum.up, float3(0, 1, 0));

	frustum.front = matrix.MulDir(frustum.front).Normalized();
	frustum.up = matrix.MulDir(frustum.up).Normalized();
}

Culling CompCamera::ContainsAABox(const AABB& refBox) const
{
	float3 corner[8];
	int totalIn = 0;
	refBox.GetCornerPoints(corner); // get the corners of the box into corner array

	// Test all 8 corners against the 6 sides of the frustum.
	// If all of them are behinf one specific plane = OUT.
	// If one of them is inside all the planes = IN or INTERSECT
	for (uint p = 0; p < 6; p++)
	{
		int In_count = 8;
		int point_In = 1;

		for(uint i = 0; i < 8; i++)
		{
			//Test all points against plane[p]
			if (frustum.GetPlane(p).IsOnPositiveSide(corner[i]))
			{
				// The point is behind the plane
				point_In = 0;
				In_count--;
			}
		}

		// If all points are out of the plane
		if (In_count == 0)
		{
			return CULL_OUT;
		}

		// Sum all points that are inside of the planes
		totalIn += point_In;
	}

	if (totalIn == 6)
	{
		return CULL_IN;
	}

	return CULL_INTERSECT;
}

void CompCamera::SetMain(bool isMain)
{
	if (isMain)
	{
		App->renderer3D->SetGameCamera(this);
	}
	else
	{
		App->renderer3D->SetGameCamera(nullptr);
	}

	// Set output variable to check on inspector
	is_main = isMain;
}

void CompCamera::SetPos(float3 pos)
{
	frustum.pos = pos;
}

void CompCamera::SetNear(float near_p)
{
	frustum.nearPlaneDistance = near_p;
}

void CompCamera::SetFar(float far_p)
{
	frustum.farPlaneDistance = far_p;
}

void CompCamera::SetFov(float vertical)
{
	frustum.verticalFov = vertical * DEGTORAD;
	frustum.horizontalFov = Atan(aspect_ratio*Tan(frustum.verticalFov / 2)) * 2;
}

void CompCamera::SetRatio(float ratio)
{
	aspect_ratio = ratio;
	frustum.horizontalFov = Atan(aspect_ratio*Tan(frustum.verticalFov / 2)) * 2;
}

float CompCamera::GetNear() const
{
	return frustum.nearPlaneDistance;
}

float CompCamera::GetFar() const
{
	return frustum.farPlaneDistance;
}

float CompCamera::GetFOV() const
{
	return frustum.verticalFov * RADTODEG;
}

float CompCamera::GetRatio() const
{
	return frustum.AspectRatio();
}

float* CompCamera::GetViewMatrix() const
{
	static float4x4 matrix;
	matrix = frustum.ViewMatrix();
	matrix.Transpose();

	return (float*)matrix.v;
}

float* CompCamera::GetProjectionMatrix() const
{
	static float4x4 matrix;
	matrix = frustum.ProjectionMatrix();
	matrix.Transpose();

	return (float*)matrix.v;
}

void CompCamera::Save(JSON_Object * object, std::string name) const
{
	// TRANSFORM-----------
	json_object_dotset_number_with_std(object, name + "Type", C_CAMERA);
	// Position
	App->fs->json_array_dotset_float3(object, name + "Position", frustum.pos);
	App->fs->json_array_dotset_float3(object, name + "Front", frustum.front);
	App->fs->json_array_dotset_float3(object, name + "Up", frustum.up);

	json_object_dotset_number_with_std(object, name + "Near Plane", frustum.nearPlaneDistance);
	json_object_dotset_number_with_std(object, name + "Far Plane", frustum.farPlaneDistance);
	json_object_dotset_number_with_std(object, name + "Vertical Pov", frustum.verticalFov);

	json_object_dotset_boolean_with_std(object, name + "Main Camera", is_main);
}

void CompCamera::Load(const JSON_Object * object, std::string name)
{
	frustum.pos = App->fs->json_array_dotget_float3_string(object, name + "Position");
	frustum.front = App->fs->json_array_dotget_float3_string(object, name + "Front");
	frustum.up = App->fs->json_array_dotget_float3_string(object, name + "Up");
	frustum.nearPlaneDistance = json_object_dotget_number_with_std(object, name + "Near Plane");
	frustum.farPlaneDistance = json_object_dotget_number_with_std(object, name + "Far Plane");
	frustum.verticalFov = json_object_dotget_number_with_std(object, name + "Vertical Pov");

	near_plane = frustum.nearPlaneDistance;
	far_plane = frustum.farPlaneDistance;
	vertical_fov = frustum.verticalFov;

	is_main = json_object_dotget_boolean_with_std(object, name + "Main Camera");
	SetMain(is_main);

	Enable();
}
<commit_msg>Culling for dynamic objects well implemented<commit_after>#include "CompCamera.h"
#include "CompMesh.h"
#include "CompTransform.h"
#include "MathGeoLib.h"
#include "Application.h"
#include "Scene.h"
#include "ModuleFS.h"
#include "ModuleRenderer3D.h"
#include "GameObject.h"

#include "SDL\include\SDL_opengl.h"
#include <math.h>

CompCamera::CompCamera(Comp_Type t, GameObject* parent) : Component(t, parent)
{
	nameComponent = "Camera";
	//uid = App->random->Int();
	/* Set camera vars*/
	width = 16;
	height = 9;
	aspect_ratio = width / height; // We set aspect ratio 16:9 by now

	near_plane = 0.2;
	far_plane = 1000;
	vertical_fov = 60; /* In degrees */

	/* Set frustum vars */
	frustum.type = PerspectiveFrustum;
	frustum.pos.Set(0, 0, 0);
	frustum.front.Set(0, 0, 1);
	frustum.up.Set(0, 1, 0);

	frustum.nearPlaneDistance = near_plane;
	frustum.farPlaneDistance = far_plane;
	frustum.verticalFov = vertical_fov * DEGTORAD;
	frustum.horizontalFov = Atan(aspect_ratio*Tan(frustum.verticalFov / 2)) * 2;
}

CompCamera::~CompCamera()
{
}

void CompCamera::preUpdate(float dt)
{
	if (culling)
	{
		// Iterate All GameObjects and apply culling
		DoCulling();
	}
}

void CompCamera::Update(float dt)
{
	UpdateFrustum();
}

void CompCamera::UpdateFrustum()
{
	const CompTransform* transform = parent->GetComponentTransform();

	float4x4 trans = transform->GetGlobalTransform();

	frustum.pos = trans.TranslatePart();
	frustum.front = trans.WorldZ();
	frustum.up = frustum.front.Cross(-frustum.WorldRight());
}

void CompCamera::Draw()
{
	// if(parent->selected == true)
	DebugDraw();
}

void CompCamera::DebugDraw()
{
	glBindTexture(GL_TEXTURE_2D, 0);
	glBegin(GL_LINES);
	glLineWidth(3.0f);
	glColor4f(0.25f, 1.0f, 0.0f, 1.0f);

	for (uint i = 0; i < 12; i++)
	{
		glVertex3f(frustum.Edge(i).a.x, frustum.Edge(i).a.y, frustum.Edge(i).a.z);
		glVertex3f(frustum.Edge(i).b.x, frustum.Edge(i).b.y, frustum.Edge(i).b.z);
	}

	glEnd();
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
}

void CompCamera::ShowOptions()
{
	//ImGui::MenuItem("CREATE", NULL, false, false);
	if (ImGui::MenuItem("Reset"))
	{
		// Not implmented yet.
	}
	ImGui::Separator();
	if (ImGui::MenuItem("Move to Front", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Move to Back", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Remove Component"))
	{
		toDelete = true;
	}
	if (ImGui::MenuItem("Move Up", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Move Down", NULL, false, false))
	{
		// Not implmented yet.
	}
	if (ImGui::MenuItem("Copy Component"))
	{
		// Component* Copy = this;
	}
	if (ImGui::MenuItem("Paste Component", NULL, false, false))
	{
		//parent->AddComponent(App->scene->copyComponent->GetType())
		// Create contructor Component Copy or add funtion to add info
	}
}

void CompCamera::ShowInspectorInfo()
{
	// Reset Values Button -------------------------------------------
	ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3, 0));
	ImGui::SameLine(ImGui::GetWindowWidth() - 26);
	if (ImGui::ImageButton((ImTextureID*)App->scene->icon_options_transform, ImVec2(13, 13), ImVec2(-1, 1), ImVec2(0, 0)))
	{
		// Open Options
	}
	ImGui::PopStyleVar();

	if (ImGui::Checkbox("Main Camera", &is_main))
	{
		SetMain(is_main);
	}

	if (ImGui::Checkbox("Culling", &culling))
	{
		if (!culling)
		{
			UnCull();
		}
	}

	ImGui::PushItemWidth(80);
	if (ImGui::DragFloat("Near Plane", &near_plane, 0.5f, 0.01f, far_plane - 0.01f))
	{
		SetNear(near_plane);
	}
	if (ImGui::DragFloat("Far Plane", &far_plane, 0.5f, near_plane + 0.01f, 1000.0f))
	{
		SetFar(far_plane);
	}
	if (ImGui::SliderFloat("FOV", &vertical_fov, 1, 179))
	{
		SetFov(vertical_fov);
	}

	ImGui::PopItemWidth();
	ImGui::TreePop();
}

void CompCamera::DoCulling()
{
	// First check culling with static objects (optimized with quadtree)
	CullStaticObjects();

	// Then check dynamic objects
	CullDynamicObjects();
}

void CompCamera::CullStaticObjects()
{
	// Set all static objects invisible first
	for (uint i = 0; i < App->scene->static_objects.size(); i++)
	{
		App->scene->static_objects[i]->SetVisible(false);
	}

	candidates_to_cull.clear();
	// Get all static objects that are inside the frustum (accelerated with quadtree)
	App->scene->quadtree.CollectCandidates(candidates_to_cull, frustum);

	// Set visible only these static objects
	for (uint i = 0; i < candidates_to_cull.size(); i++)
	{
		candidates_to_cull[i]->SetVisible(true);
	}
}

void CompCamera::CullDynamicObjects()
{
	AABB* box = nullptr;
	candidates_to_cull.clear();

	// Push all active elements that are root and are active
	for (uint i = 0; i < App->scene->gameobjects.size(); i++)
	{
		if (App->scene->gameobjects[i]->isActive())
		{
			candidates_to_cull.push_back(App->scene->gameobjects[i]);
		}
	}

	// Check candidates_to_cull vector until it's empty
	while (candidates_to_cull.empty() == false)
	{
		if (!candidates_to_cull.front()->isStatic())
		{
			box = &candidates_to_cull.front()->box_fixed;
			if (box != nullptr && candidates_to_cull.front() != parent)
			{
				if (ContainsAABox(*box) == CULL_OUT)
				{
					candidates_to_cull.front()->SetVisible(false);
				}
				else
				{
					candidates_to_cull.front()->SetVisible(true);
				}
			}
		}

		//Push all childs that are active to candidates vector
		for (std::vector<GameObject*>::iterator it = candidates_to_cull.front()->GetChildsVec().begin(); it != candidates_to_cull.front()->GetChildsVec().end(); it++)
		{
			if (!((GameObject*)*it)->isActive())
			{
				candidates_to_cull.push_back((*it));
			}
		}
		// delete from vector the object already checked
		candidates_to_cull.pop_back();
	}
}

void CompCamera::UnCull()
{
	for (uint i = 0; i < App->scene->gameobjects.size(); i++)
	{
		if (App->scene->gameobjects[i]->isActive())
		{
			App->scene->gameobjects[i]->SetVisible(true);
		}
	}
}

void CompCamera::LookAt(const float3& position)
{
	float3 direction = position - frustum.pos;
	float3x3 matrix = float3x3::LookAt(frustum.front, direction.Normalized(), frustum.up, float3(0, 1, 0));

	frustum.front = matrix.MulDir(frustum.front).Normalized();
	frustum.up = matrix.MulDir(frustum.up).Normalized();
}

Culling CompCamera::ContainsAABox(const AABB& refBox) const
{
	float3 corner[8];
	int totalIn = 0;
	refBox.GetCornerPoints(corner); // get the corners of the box into corner array

	// Test all 8 corners against the 6 sides of the frustum.
	// If all of them are behinf one specific plane = OUT.
	// If one of them is inside all the planes = IN or INTERSECT
	for (uint p = 0; p < 6; p++)
	{
		int In_count = 8;
		int point_In = 1;

		for(uint i = 0; i < 8; i++)
		{
			//Test all points against plane[p]
			if (frustum.GetPlane(p).IsOnPositiveSide(corner[i]))
			{
				// The point is behind the plane
				point_In = 0;
				In_count--;
			}
		}

		// If all points are out of the plane
		if (In_count == 0)
		{
			return CULL_OUT;
		}

		// Sum all points that are inside of the planes
		totalIn += point_In;
	}

	if (totalIn == 6)
	{
		return CULL_IN;
	}

	return CULL_INTERSECT;
}

void CompCamera::SetMain(bool isMain)
{
	if (isMain)
	{
		App->renderer3D->SetGameCamera(this);
	}
	else
	{
		App->renderer3D->SetGameCamera(nullptr);
	}

	// Set output variable to check on inspector
	is_main = isMain;
}

void CompCamera::SetPos(float3 pos)
{
	frustum.pos = pos;
}

void CompCamera::SetNear(float near_p)
{
	frustum.nearPlaneDistance = near_p;
}

void CompCamera::SetFar(float far_p)
{
	frustum.farPlaneDistance = far_p;
}

void CompCamera::SetFov(float vertical)
{
	frustum.verticalFov = vertical * DEGTORAD;
	frustum.horizontalFov = Atan(aspect_ratio*Tan(frustum.verticalFov / 2)) * 2;
}

void CompCamera::SetRatio(float ratio)
{
	aspect_ratio = ratio;
	frustum.horizontalFov = Atan(aspect_ratio*Tan(frustum.verticalFov / 2)) * 2;
}

float CompCamera::GetNear() const
{
	return frustum.nearPlaneDistance;
}

float CompCamera::GetFar() const
{
	return frustum.farPlaneDistance;
}

float CompCamera::GetFOV() const
{
	return frustum.verticalFov * RADTODEG;
}

float CompCamera::GetRatio() const
{
	return frustum.AspectRatio();
}

float* CompCamera::GetViewMatrix() const
{
	static float4x4 matrix;
	matrix = frustum.ViewMatrix();
	matrix.Transpose();

	return (float*)matrix.v;
}

float* CompCamera::GetProjectionMatrix() const
{
	static float4x4 matrix;
	matrix = frustum.ProjectionMatrix();
	matrix.Transpose();

	return (float*)matrix.v;
}

void CompCamera::Save(JSON_Object * object, std::string name) const
{
	// TRANSFORM-----------
	json_object_dotset_number_with_std(object, name + "Type", C_CAMERA);
	// Position
	App->fs->json_array_dotset_float3(object, name + "Position", frustum.pos);
	App->fs->json_array_dotset_float3(object, name + "Front", frustum.front);
	App->fs->json_array_dotset_float3(object, name + "Up", frustum.up);

	json_object_dotset_number_with_std(object, name + "Near Plane", frustum.nearPlaneDistance);
	json_object_dotset_number_with_std(object, name + "Far Plane", frustum.farPlaneDistance);
	json_object_dotset_number_with_std(object, name + "Vertical Pov", frustum.verticalFov);

	json_object_dotset_boolean_with_std(object, name + "Main Camera", is_main);
}

void CompCamera::Load(const JSON_Object * object, std::string name)
{
	frustum.pos = App->fs->json_array_dotget_float3_string(object, name + "Position");
	frustum.front = App->fs->json_array_dotget_float3_string(object, name + "Front");
	frustum.up = App->fs->json_array_dotget_float3_string(object, name + "Up");
	frustum.nearPlaneDistance = json_object_dotget_number_with_std(object, name + "Near Plane");
	frustum.farPlaneDistance = json_object_dotget_number_with_std(object, name + "Far Plane");
	frustum.verticalFov = json_object_dotget_number_with_std(object, name + "Vertical Pov");

	near_plane = frustum.nearPlaneDistance;
	far_plane = frustum.farPlaneDistance;
	vertical_fov = frustum.verticalFov;

	is_main = json_object_dotget_boolean_with_std(object, name + "Main Camera");
	SetMain(is_main);

	Enable();
}
<|endoftext|>


<commit_before>#include "terrainer.hpp"
#include "helpers.hpp"
#include "node.hpp"
#include "parametric_shapes.cpp"

#include "config.hpp"
#include "external/glad/glad.h"
#include "core/Bonobo.h"
#include "core/FPSCamera.h"
#include "core/GLStateInspection.h"
#include "core/GLStateInspectionView.h"
#include "core/InputHandler.h"
#include "core/Log.h"
#include "core/LogView.h"
#include "core/Misc.h"
#include "core/utils.h"
#include "core/Window.h"
#include <imgui.h>
#include "external/imgui_impl_glfw_gl3.h"

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "external/glad/glad.h"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <array>
#include <cstdlib>
#include <stdexcept>

enum class polygon_mode_t : unsigned int {
    fill = 0u,
    line,
    point
};

static polygon_mode_t get_next_mode(polygon_mode_t mode)
{
    return static_cast<polygon_mode_t>((static_cast<unsigned int>(mode) + 1u) % 3u);
}

namespace constant
{
    constexpr uint32_t shadowmap_res_x = 1024;
    constexpr uint32_t shadowmap_res_y = 1024;

    constexpr size_t lights_nb           = 4;
    constexpr float  light_intensity     = 720000.0f;
    constexpr float  light_angle_falloff = 0.8f;
    constexpr float  light_cutoff        = 0.05f;
}

static eda221::mesh_data loadCone();

edan35::Terrainer::Terrainer()
{
    Log::View::Init();

    window = Window::Create("Terrainer", config::resolution_x,
                            config::resolution_y, config::msaa_rate, false, false);
    if (window == nullptr) {
        Log::View::Destroy();
        throw std::runtime_error("Failed to get a window: aborting!");
    }
    inputHandler = new InputHandler();
    window->SetInputHandler(inputHandler);

    GLStateInspection::Init();
    GLStateInspection::View::Init();

    eda221::init();
}

edan35::Terrainer::~Terrainer()
{
    eda221::deinit();

    GLStateInspection::View::Destroy();
    GLStateInspection::Destroy();

    delete inputHandler;
    inputHandler = nullptr;

    Window::Destroy(window);
    window = nullptr;

    Log::View::Destroy();
}

void
edan35::Terrainer::run()
{
    auto const window_size = window->GetDimensions();

    //
    // Setup the camera
    //
    FPSCameraf mCamera(bonobo::pi / 4.0f,
                       static_cast<float>(window_size.x) / static_cast<float>(window_size.y),
                       1.0f, 10000.0f);
    mCamera.mWorld.SetTranslate(glm::vec3(0.0f, 100.0f, 180.0f));
    mCamera.mWorld.LookAt(glm::vec3(0.0f, 0.0f, 0.0f));
    mCamera.mMouseSensitivity = 0.003f;
    mCamera.mMovementSpeed = 0.25f;
    window->SetCamera(&mCamera);

    eda221::mesh_data quad = parametric_shapes::createQuad(100, 100, 100, 100);

    //
    // Load all the shader programs used
    //
    auto fallback_shader = eda221::createProgram("fallback.vert", "fallback.frag");
    if (fallback_shader == 0u) {
        LogError("Failed to load fallback shader");
        return;
    }

    auto const reload_shader = [fallback_shader](std::string const& vertex_path, std::string const& fragment_path, GLuint& program){
        if (program != 0u && program != fallback_shader)
            glDeleteProgram(program);
        program = eda221::createProgram("../EDAN35/" + vertex_path, "../EDAN35/" + fragment_path);
        if (program == 0u) {
            LogError("Failed to load \"%s\" and \"%s\"", vertex_path.c_str(), fragment_path.c_str());
            program = fallback_shader;
        }
    };

    GLuint fill_gbuffer_shader = 0u, fill_shadowmap_shader = 0u, accumulate_lights_shader = 0u, resolve_deferred_shader = 0u;
    auto const reload_shaders = [&reload_shader,&fill_gbuffer_shader,&fill_shadowmap_shader,&accumulate_lights_shader,&resolve_deferred_shader](){
        LogInfo("Reloading shaders");
        reload_shader("fill_gbuffer.vert",      "fill_gbuffer.frag",      fill_gbuffer_shader);
        reload_shader("fill_shadowmap.vert",    "fill_shadowmap.frag",    fill_shadowmap_shader);
        reload_shader("accumulate_lights.vert", "accumulate_lights.frag", accumulate_lights_shader);
        reload_shader("resolve_deferred.vert",  "resolve_deferred.frag",  resolve_deferred_shader);
    };
    reload_shaders();

    auto const set_uniforms = [](GLuint /*program*/){};

    auto quad_node = Node();
    quad_node.set_geometry(quad);
    quad_node.set_program(fallback_shader, set_uniforms);

    /*
    // Setup textures
    //
    auto const diffuse_texture                     = eda221::createTexture(window_size.x, window_size.y);
    auto const specular_texture                    = eda221::createTexture(window_size.x, window_size.y);
    auto const normal_texture                      = eda221::createTexture(window_size.x, window_size.y);
    auto const light_diffuse_contribution_texture  = eda221::createTexture(window_size.x, window_size.y);
    auto const light_specular_contribution_texture = eda221::createTexture(window_size.x, window_size.y);
    auto const depth_texture                       = eda221::createTexture(window_size.x, window_size.y, GL_TEXTURE_2D, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
    auto const shadowmap_texture                   = eda221::createTexture(constant::shadowmap_res_x, constant::shadowmap_res_y, GL_TEXTURE_2D, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
    */

    /*
    //
    // Setup FBOs
    //
    auto const deferred_fbo  = eda221::createFBO({diffuse_texture, specular_texture, normal_texture}, depth_texture);
    auto const shadowmap_fbo = eda221::createFBO({}, shadowmap_texture);
    auto const light_fbo     = eda221::createFBO({light_diffuse_contribution_texture, light_specular_contribution_texture}, depth_texture);

    //
    // Setup samplers
    //
    auto const default_sampler = eda221::createSampler([](GLuint sampler){
        glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    });

    auto const depth_sampler = eda221::createSampler([](GLuint sampler){
        glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    });

    auto const shadow_sampler = eda221::createSampler([](GLuint sampler){
        glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
        glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
        GLfloat border_color[4] = { 1.0f, 0.0f, 0.0f, 0.0f};
        glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, border_color);
    });

    auto const bind_texture_with_sampler = [](GLenum target, unsigned int slot, GLuint program, std::string const& name, GLuint texture, GLuint sampler){
        glActiveTexture(GL_TEXTURE0 + slot);
        glBindTexture(target, texture);
        glUniform1i(glGetUniformLocation(program, name.c_str()), static_cast<GLint>(slot));
        glBindSampler(slot, sampler);
    };
    */

    auto seconds_nb = 0.0f;

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    double ddeltatime;
    size_t fpsSamples = 0;
    double nowTime, lastTime = GetTimeMilliseconds();
    double fpsNextTick = lastTime + 1000.0;

    while (!glfwWindowShouldClose(window->GetGLFW_Window())) {
        nowTime = GetTimeMilliseconds();
        ddeltatime = nowTime - lastTime;
        if (nowTime > fpsNextTick) {
            fpsNextTick += 1000.0;
            fpsSamples = 0;
        }
        fpsSamples++;
        seconds_nb += static_cast<float>(ddeltatime / 1000.0);

        glfwPollEvents();
        inputHandler->Advance();
        mCamera.Update(ddeltatime, *inputHandler);

        ImGui_ImplGlfwGL3_NewFrame();

        if (inputHandler->GetKeycodeState(GLFW_KEY_R) & JUST_PRESSED) {
            reload_shaders();
        }

        glCullFace(GL_BACK);
        glDepthFunc(GL_ALWAYS);
	quad_node.render(mCamera.GetWorldToClipMatrix(), quad_node.get_transform());
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

        GLStateInspection::View::Render();
        Log::View::Render();

        bool opened = ImGui::Begin("Render Time", nullptr, ImVec2(120, 50), -1.0f, 0);
        if (opened)
            ImGui::Text("%.3f ms", ddeltatime);
        ImGui::End();

        ImGui::Render();

        window->Swap();
        lastTime = nowTime;
    }

    glDeleteProgram(resolve_deferred_shader);
    resolve_deferred_shader = 0u;
    glDeleteProgram(accumulate_lights_shader);
    accumulate_lights_shader = 0u;
    glDeleteProgram(fill_shadowmap_shader);
    fill_shadowmap_shader = 0u;
    glDeleteProgram(fill_gbuffer_shader);
    fill_gbuffer_shader = 0u;
    glDeleteProgram(fallback_shader);
    fallback_shader = 0u;
}

int main()
{
    Bonobo::Init();
    try {
        edan35::Terrainer terrainer;
        terrainer.run();
    } catch (std::runtime_error const& e) {
        LogError(e.what());
    }
    Bonobo::Destroy();
}
<commit_msg>added some polygonmode config, unsure if it matters<commit_after>#include "terrainer.hpp"
#include "helpers.hpp"
#include "node.hpp"
#include "parametric_shapes.cpp"

#include "config.hpp"
#include "external/glad/glad.h"
#include "core/Bonobo.h"
#include "core/FPSCamera.h"
#include "core/GLStateInspection.h"
#include "core/GLStateInspectionView.h"
#include "core/InputHandler.h"
#include "core/Log.h"
#include "core/LogView.h"
#include "core/Misc.h"
#include "core/utils.h"
#include "core/Window.h"
#include <imgui.h>
#include "external/imgui_impl_glfw_gl3.h"

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "external/glad/glad.h"
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <array>
#include <cstdlib>
#include <stdexcept>

enum class polygon_mode_t : unsigned int {
    fill = 0u,
    line,
    point
};

static polygon_mode_t get_next_mode(polygon_mode_t mode)
{
    return static_cast<polygon_mode_t>((static_cast<unsigned int>(mode) + 1u) % 3u);
}

namespace constant
{
    constexpr uint32_t shadowmap_res_x = 1024;
    constexpr uint32_t shadowmap_res_y = 1024;

    constexpr size_t lights_nb           = 4;
    constexpr float  light_intensity     = 720000.0f;
    constexpr float  light_angle_falloff = 0.8f;
    constexpr float  light_cutoff        = 0.05f;
}

static eda221::mesh_data loadCone();

edan35::Terrainer::Terrainer()
{
    Log::View::Init();

    window = Window::Create("Terrainer", config::resolution_x,
                            config::resolution_y, config::msaa_rate, false, false);
    if (window == nullptr) {
        Log::View::Destroy();
        throw std::runtime_error("Failed to get a window: aborting!");
    }
    inputHandler = new InputHandler();
    window->SetInputHandler(inputHandler);

    GLStateInspection::Init();
    GLStateInspection::View::Init();

    eda221::init();
}

edan35::Terrainer::~Terrainer()
{
    eda221::deinit();

    GLStateInspection::View::Destroy();
    GLStateInspection::Destroy();

    delete inputHandler;
    inputHandler = nullptr;

    Window::Destroy(window);
    window = nullptr;

    Log::View::Destroy();
}

void
edan35::Terrainer::run()
{
    auto const window_size = window->GetDimensions();

    //
    // Setup the camera
    //
    FPSCameraf mCamera(bonobo::pi / 4.0f,
                       static_cast<float>(window_size.x) / static_cast<float>(window_size.y),
                       1.0f, 10000.0f);
    mCamera.mWorld.SetTranslate(glm::vec3(0.0f, 100.0f, 180.0f));
    mCamera.mWorld.LookAt(glm::vec3(0.0f, 0.0f, 0.0f));
    mCamera.mMouseSensitivity = 0.003f;
    mCamera.mMovementSpeed = 0.25f;
    window->SetCamera(&mCamera);

    eda221::mesh_data quad = parametric_shapes::createQuad(100, 100, 100, 100);

    //
    // Load all the shader programs used
    //
    auto fallback_shader = eda221::createProgram("fallback.vert", "fallback.frag");
    if (fallback_shader == 0u) {
        LogError("Failed to load fallback shader");
        return;
    }

    auto const reload_shader = [fallback_shader](std::string const& vertex_path, std::string const& fragment_path, GLuint& program){
        if (program != 0u && program != fallback_shader)
            glDeleteProgram(program);
        program = eda221::createProgram("../EDAN35/" + vertex_path, "../EDAN35/" + fragment_path);
        if (program == 0u) {
            LogError("Failed to load \"%s\" and \"%s\"", vertex_path.c_str(), fragment_path.c_str());
            program = fallback_shader;
        }
    };

    GLuint fill_gbuffer_shader = 0u, fill_shadowmap_shader = 0u, accumulate_lights_shader = 0u, resolve_deferred_shader = 0u;
    auto const reload_shaders = [&reload_shader,&fill_gbuffer_shader,&fill_shadowmap_shader,&accumulate_lights_shader,&resolve_deferred_shader](){
        LogInfo("Reloading shaders");
        reload_shader("fill_gbuffer.vert",      "fill_gbuffer.frag",      fill_gbuffer_shader);
        reload_shader("fill_shadowmap.vert",    "fill_shadowmap.frag",    fill_shadowmap_shader);
        reload_shader("accumulate_lights.vert", "accumulate_lights.frag", accumulate_lights_shader);
        reload_shader("resolve_deferred.vert",  "resolve_deferred.frag",  resolve_deferred_shader);
    };
    reload_shaders();

    auto const set_uniforms = [](GLuint /*program*/){};

    auto quad_node = Node();
    quad_node.set_geometry(quad);
    quad_node.set_program(fallback_shader, set_uniforms);

    /*
    // Setup textures
    //
    auto const diffuse_texture                     = eda221::createTexture(window_size.x, window_size.y);
    auto const specular_texture                    = eda221::createTexture(window_size.x, window_size.y);
    auto const normal_texture                      = eda221::createTexture(window_size.x, window_size.y);
    auto const light_diffuse_contribution_texture  = eda221::createTexture(window_size.x, window_size.y);
    auto const light_specular_contribution_texture = eda221::createTexture(window_size.x, window_size.y);
    auto const depth_texture                       = eda221::createTexture(window_size.x, window_size.y, GL_TEXTURE_2D, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
    auto const shadowmap_texture                   = eda221::createTexture(constant::shadowmap_res_x, constant::shadowmap_res_y, GL_TEXTURE_2D, GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT);
    */

    /*
    //
    // Setup FBOs
    //
    auto const deferred_fbo  = eda221::createFBO({diffuse_texture, specular_texture, normal_texture}, depth_texture);
    auto const shadowmap_fbo = eda221::createFBO({}, shadowmap_texture);
    auto const light_fbo     = eda221::createFBO({light_diffuse_contribution_texture, light_specular_contribution_texture}, depth_texture);

    //
    // Setup samplers
    //
    auto const default_sampler = eda221::createSampler([](GLuint sampler){
        glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    });

    auto const depth_sampler = eda221::createSampler([](GLuint sampler){
        glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    });

    auto const shadow_sampler = eda221::createSampler([](GLuint sampler){
        glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
        glSamplerParameteri(sampler, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
        GLfloat border_color[4] = { 1.0f, 0.0f, 0.0f, 0.0f};
        glSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR, border_color);
    });

    auto const bind_texture_with_sampler = [](GLenum target, unsigned int slot, GLuint program, std::string const& name, GLuint texture, GLuint sampler){
        glActiveTexture(GL_TEXTURE0 + slot);
        glBindTexture(target, texture);
        glUniform1i(glGetUniformLocation(program, name.c_str()), static_cast<GLint>(slot));
        glBindSampler(slot, sampler);
    };
    */

    auto seconds_nb = 0.0f;

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    double ddeltatime;
    size_t fpsSamples = 0;
    double nowTime, lastTime = GetTimeMilliseconds();
    double fpsNextTick = lastTime + 1000.0;

    while (!glfwWindowShouldClose(window->GetGLFW_Window())) {
        nowTime = GetTimeMilliseconds();
        ddeltatime = nowTime - lastTime;
        if (nowTime > fpsNextTick) {
            fpsNextTick += 1000.0;
            fpsSamples = 0;
        }
        fpsSamples++;
        seconds_nb += static_cast<float>(ddeltatime / 1000.0);

        glfwPollEvents();
        inputHandler->Advance();
        mCamera.Update(ddeltatime, *inputHandler);

        ImGui_ImplGlfwGL3_NewFrame();

        if (inputHandler->GetKeycodeState(GLFW_KEY_R) & JUST_PRESSED) {
            reload_shaders();
        }

        glCullFace(GL_BACK);
        //glDepthFunc(GL_ALWAYS);
	quad_node.render(mCamera.GetWorldToClipMatrix(), quad_node.get_transform());
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

        GLStateInspection::View::Render();
        Log::View::Render();

        bool opened = ImGui::Begin("Render Time", nullptr, ImVec2(120, 50), -1.0f, 0);
        if (opened)
            ImGui::Text("%.3f ms", ddeltatime);
        ImGui::End();

        ImGui::Render();

        window->Swap();
        lastTime = nowTime;
    }

    glDeleteProgram(resolve_deferred_shader);
    resolve_deferred_shader = 0u;
    glDeleteProgram(accumulate_lights_shader);
    accumulate_lights_shader = 0u;
    glDeleteProgram(fill_shadowmap_shader);
    fill_shadowmap_shader = 0u;
    glDeleteProgram(fill_gbuffer_shader);
    fill_gbuffer_shader = 0u;
    glDeleteProgram(fallback_shader);
    fallback_shader = 0u;
}

int main()
{
    Bonobo::Init();
    try {
        edan35::Terrainer terrainer;
        terrainer.run();
    } catch (std::runtime_error const& e) {
        LogError(e.what());
    }
    Bonobo::Destroy();
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "EsriClientThread.h"
#include "EsriHandler.h"
#include "EsriInternalCommands.h"
#include "strOps.h"
#include <algorithm>
#include <string.h>

namespace libESRI
{
  EsriClientThread::EsriClientThread(toni::TcpClient* tcpClient, EsriHandler* handler)
    : m_tcpClient(tcpClient)
    , m_handler(handler)
    , m_TelnetLib(nullptr)
  {
    m_InternalHandler = new EsriInternalCommands(handler);
  }

  EsriClientThread::~EsriClientThread()
  {
    if (m_TelnetLib)
    {
      telnet_free(m_TelnetLib);
      m_TelnetLib = nullptr;
    }

    delete m_InternalHandler;
  }

  bool EsriClientThread::SendWelcomeMessage()
  {
    char const * const welcomeMessage = m_handler->OnProvideWelcomeMessage();
    if (welcomeMessage)
    {
      size_t welcomeMessageLength = strlen(welcomeMessage);
      telnet_send(m_TelnetLib, welcomeMessage, welcomeMessageLength);
    }

    return true;
  }

  bool EsriClientThread::SendCurrentDirectory()
  {
    char const * const curDir = m_handler->OnGetCurrentDirectory();
    if (curDir)
    {
      std::string currentDirectory = curDir;
      currentDirectory += ">";
      return m_tcpClient->Send(currentDirectory.c_str(), (int)currentDirectory.length()) > 0;
    }

    return true;
  }

  void EsriClientThread::AutoComplete(std::string& input, std::string& commonStartOfAllCandidates, std::vector<std::string>& candidates)
  {
    auto* allCommandsAsString = m_handler->OnProvideCommands();
    if (!allCommandsAsString)
    {
      commonStartOfAllCandidates = input;
      return;
    }

    std::string allCommandsStringBuffer = allCommandsAsString;
    allCommandsStringBuffer += m_InternalHandler->ProvideInternalCommands();
    auto allCommands = toni::Tokenize<std::string>(allCommandsStringBuffer, ";");
    for (auto& candidate : allCommands)
    {
      if (!candidate.empty() && candidate.find(input) == 0)
        candidates.push_back(candidate);
    }

    if (candidates.empty())
    {
      commonStartOfAllCandidates = input;
      return;
    }

    if (candidates.size() == 1)
    {
      commonStartOfAllCandidates = candidates[0];
      return;
    }

    //candidates.size() now >= 2
    std::sort(candidates.begin(), candidates.end());

    std::string& first = candidates[0];
    std::string& last = candidates[candidates.size() - 1];

    size_t shortestCandidate = std::min(first.size(), last.size());
    commonStartOfAllCandidates = "";
    for (size_t i = 0; i < shortestCandidate; i++)
    {
      if (first[i] == last[i])
        commonStartOfAllCandidates += first[i];
      else
        break;
    }
  }

  bool EsriClientThread::HandleAutoComplete(std::string& input)
  {
    std::string autoCompletedInput;
    std::vector<std::string> otherCandidates;
    AutoComplete(input, autoCompletedInput, otherCandidates);

    if (otherCandidates.size() > 1)
    {
      std::string allCandidates = "\r\n";
      for (auto& candidate : otherCandidates)
      {
        allCandidates += '\t' + candidate + "\r\n";
      }

      input = autoCompletedInput;

      allCandidates += m_handler->OnGetCurrentDirectory();
      allCandidates += ">";
      allCandidates += input;
      return m_tcpClient->Send(allCandidates.c_str(), (int)allCandidates.length()) > 0;
    }
    else
    {
      input = autoCompletedInput;

      std::string autoCompletedInputWithPrompt = "\r";
      autoCompletedInputWithPrompt += m_handler->OnGetCurrentDirectory();
      autoCompletedInputWithPrompt += ">";
      autoCompletedInputWithPrompt += input;
      return m_tcpClient->Send(autoCompletedInputWithPrompt.c_str(), (int)autoCompletedInputWithPrompt.length()) > 0;
    }
  }

  void EsriClientThread::OnTelnetEvent(telnet_event_t *ev)
  {
    switch (ev->type)
    {
      case TELNET_EV_DATA:
        m_recvBufferAfterTelnet.resize(ev->data.size);
        memcpy(m_recvBufferAfterTelnet.data(), ev->data.buffer, ev->data.size);
        break;
      case TELNET_EV_SEND:
        m_tcpClient->Send(ev->data.buffer, ev->data.size);
        break;
    }
  }

  int EsriClientThread::OnShellRequiresRead(char* targetBuffer, int bytesToRead)
  {
    std::vector<char> rawNetworkData;
    rawNetworkData.resize(bytesToRead);
    m_tcpClient->Recv(rawNetworkData.data(), bytesToRead);

    telnet_recv(m_TelnetLib, rawNetworkData.data(), rawNetworkData.size());

    memcpy(targetBuffer, m_recvBufferAfterTelnet.data(), m_recvBufferAfterTelnet.size());
    m_recvBufferAfterTelnet.clear();

    return bytesToRead;
  }

  int EsriClientThread::OnShellWantsToWrite(const char* sourceData, int sourceDataSize)
  {
    telnet_send(m_TelnetLib, sourceData, sourceDataSize);
    return sourceDataSize;
  }

  int EsriClientThread::OnShellCallback(const char* textFromTerminal)
  {
    //OutputDebugStringA(textFromTerminal);
    return 0;
  }

  void EsriClientThread::EntryPoint()
  {
    auto TelnetEvent_proxy = [](telnet_t *telnet, telnet_event_t *ev, void *user_data)
    {
      EsriClientThread* clientThread = static_cast<EsriClientThread*>(user_data);
      clientThread->OnTelnetEvent(ev);
    };

    static const telnet_telopt_t telopts[] = {
      { TELNET_TELOPT_ECHO,	TELNET_WILL, TELNET_DONT }, //TELNET_TELOPT_LINEMODE
      { TELNET_TELOPT_LINEMODE,	TELNET_WILL, TELNET_DONT },
      { -1, 0, 0 }
    };

    m_TelnetLib = telnet_init(telopts, TelnetEvent_proxy, 0, this);

    auto shell_read_proxy = [](char* buffer, int count, void* userData) -> int
    {
      return static_cast<EsriClientThread*>(userData)->OnShellRequiresRead(buffer, count);
    };

    auto shell_write_proxy = [](const char* buffer, int count, void* userData) -> int
    {
      return static_cast<EsriClientThread*>(userData)->OnShellWantsToWrite(buffer, count);
    };

    auto shell_callback_proxy = [](const char* buffer, void* userData) -> int
    {
      return static_cast<EsriClientThread*>(userData)->OnShellCallback(buffer);
    };

    ntshell_init(&m_nthshell, shell_read_proxy, shell_write_proxy, shell_callback_proxy, this);
    ntshell_set_prompt(&m_nthshell, "ESRI>");

    ntshell_execute(&m_nthshell);

    if (!SendWelcomeMessage())
      return;
    //
    //if (!SendCurrentDirectory())
    //  return;

    int recvVal = 0;
    std::vector<char> receiveBuffer(1024);
    while ((recvVal = m_tcpClient->Recv(&receiveBuffer[0], (int)receiveBuffer.size())) > 0)
    {
      telnet_recv(m_TelnetLib, receiveBuffer.data(), receiveBuffer.size());
      memset(receiveBuffer.data(), 0, receiveBuffer.size());
    }
  }
}
<commit_msg>force at least putty into char-by-char mode<commit_after>#include "stdafx.h"
#include "EsriClientThread.h"
#include "EsriHandler.h"
#include "EsriInternalCommands.h"
#include "strOps.h"
#include <algorithm>
#include <string.h>

namespace libESRI
{
  EsriClientThread::EsriClientThread(toni::TcpClient* tcpClient, EsriHandler* handler)
    : m_tcpClient(tcpClient)
    , m_handler(handler)
    , m_TelnetLib(nullptr)
  {
    m_InternalHandler = new EsriInternalCommands(handler);
  }

  EsriClientThread::~EsriClientThread()
  {
    if (m_TelnetLib)
    {
      telnet_free(m_TelnetLib);
      m_TelnetLib = nullptr;
    }

    delete m_InternalHandler;
  }

  bool EsriClientThread::SendWelcomeMessage()
  {
    char const * const welcomeMessage = m_handler->OnProvideWelcomeMessage();
    if (welcomeMessage)
    {
      size_t welcomeMessageLength = strlen(welcomeMessage);
      telnet_send(m_TelnetLib, welcomeMessage, welcomeMessageLength);
    }

    return true;
  }

  bool EsriClientThread::SendCurrentDirectory()
  {
    char const * const curDir = m_handler->OnGetCurrentDirectory();
    if (curDir)
    {
      std::string currentDirectory = curDir;
      currentDirectory += ">";
      return m_tcpClient->Send(currentDirectory.c_str(), (int)currentDirectory.length()) > 0;
    }

    return true;
  }

  void EsriClientThread::AutoComplete(std::string& input, std::string& commonStartOfAllCandidates, std::vector<std::string>& candidates)
  {
    auto* allCommandsAsString = m_handler->OnProvideCommands();
    if (!allCommandsAsString)
    {
      commonStartOfAllCandidates = input;
      return;
    }

    std::string allCommandsStringBuffer = allCommandsAsString;
    allCommandsStringBuffer += m_InternalHandler->ProvideInternalCommands();
    auto allCommands = toni::Tokenize<std::string>(allCommandsStringBuffer, ";");
    for (auto& candidate : allCommands)
    {
      if (!candidate.empty() && candidate.find(input) == 0)
        candidates.push_back(candidate);
    }

    if (candidates.empty())
    {
      commonStartOfAllCandidates = input;
      return;
    }

    if (candidates.size() == 1)
    {
      commonStartOfAllCandidates = candidates[0];
      return;
    }

    //candidates.size() now >= 2
    std::sort(candidates.begin(), candidates.end());

    std::string& first = candidates[0];
    std::string& last = candidates[candidates.size() - 1];

    size_t shortestCandidate = std::min(first.size(), last.size());
    commonStartOfAllCandidates = "";
    for (size_t i = 0; i < shortestCandidate; i++)
    {
      if (first[i] == last[i])
        commonStartOfAllCandidates += first[i];
      else
        break;
    }
  }

  bool EsriClientThread::HandleAutoComplete(std::string& input)
  {
    std::string autoCompletedInput;
    std::vector<std::string> otherCandidates;
    AutoComplete(input, autoCompletedInput, otherCandidates);

    if (otherCandidates.size() > 1)
    {
      std::string allCandidates = "\r\n";
      for (auto& candidate : otherCandidates)
      {
        allCandidates += '\t' + candidate + "\r\n";
      }

      input = autoCompletedInput;

      allCandidates += m_handler->OnGetCurrentDirectory();
      allCandidates += ">";
      allCandidates += input;
      return m_tcpClient->Send(allCandidates.c_str(), (int)allCandidates.length()) > 0;
    }
    else
    {
      input = autoCompletedInput;

      std::string autoCompletedInputWithPrompt = "\r";
      autoCompletedInputWithPrompt += m_handler->OnGetCurrentDirectory();
      autoCompletedInputWithPrompt += ">";
      autoCompletedInputWithPrompt += input;
      return m_tcpClient->Send(autoCompletedInputWithPrompt.c_str(), (int)autoCompletedInputWithPrompt.length()) > 0;
    }
  }

  void EsriClientThread::OnTelnetEvent(telnet_event_t *ev)
  {
    switch (ev->type)
    {
      case TELNET_EV_DATA:
        m_recvBufferAfterTelnet.resize(ev->data.size);
        memcpy(m_recvBufferAfterTelnet.data(), ev->data.buffer, ev->data.size);
        break;
      case TELNET_EV_SEND:
        m_tcpClient->Send(ev->data.buffer, ev->data.size);
        break;
    }
  }

  int EsriClientThread::OnShellRequiresRead(char* targetBuffer, int bytesToRead)
  {
    std::vector<char> rawNetworkData;
    rawNetworkData.resize(bytesToRead);
    m_tcpClient->Recv(rawNetworkData.data(), bytesToRead);

    telnet_recv(m_TelnetLib, rawNetworkData.data(), rawNetworkData.size());

    memcpy(targetBuffer, m_recvBufferAfterTelnet.data(), m_recvBufferAfterTelnet.size());
    m_recvBufferAfterTelnet.clear();

    return bytesToRead;
  }

  int EsriClientThread::OnShellWantsToWrite(const char* sourceData, int sourceDataSize)
  {
    //OutputDebugStringA(sourceData);
    telnet_send(m_TelnetLib, sourceData, sourceDataSize);
    return sourceDataSize;
  }

  int EsriClientThread::OnShellCallback(const char* textFromTerminal)
  {
    //OutputDebugStringA(textFromTerminal);
    return 0;
  }

  void EsriClientThread::EntryPoint()
  {
    auto TelnetEvent_proxy = [](telnet_t *telnet, telnet_event_t *ev, void *user_data)
    {
      EsriClientThread* clientThread = static_cast<EsriClientThread*>(user_data);
      clientThread->OnTelnetEvent(ev);
    };

    static const telnet_telopt_t telopts[] = {
      { TELNET_TELOPT_ECHO,	TELNET_WILL, TELNET_DONT },
      { TELNET_TELOPT_SGA,	TELNET_WILL, TELNET_DO },
      { -1, 0, 0 }
    };

    m_TelnetLib = telnet_init(telopts, TelnetEvent_proxy, 0, this);

    auto shell_read_proxy = [](char* buffer, int count, void* userData) -> int
    {
      return static_cast<EsriClientThread*>(userData)->OnShellRequiresRead(buffer, count);
    };

    auto shell_write_proxy = [](const char* buffer, int count, void* userData) -> int
    {
      return static_cast<EsriClientThread*>(userData)->OnShellWantsToWrite(buffer, count);
    };

    auto shell_callback_proxy = [](const char* buffer, void* userData) -> int
    {
      return static_cast<EsriClientThread*>(userData)->OnShellCallback(buffer);
    };

    ntshell_init(&m_nthshell, shell_read_proxy, shell_write_proxy, shell_callback_proxy, this);
    ntshell_set_prompt(&m_nthshell, "ESRI>");

    ntshell_execute(&m_nthshell);

    if (!SendWelcomeMessage())
      return;
    //
    //if (!SendCurrentDirectory())
    //  return;

    int recvVal = 0;
    std::vector<char> receiveBuffer(1024);
    while ((recvVal = m_tcpClient->Recv(&receiveBuffer[0], (int)receiveBuffer.size())) > 0)
    {
      telnet_recv(m_TelnetLib, receiveBuffer.data(), receiveBuffer.size());
      memset(receiveBuffer.data(), 0, receiveBuffer.size());
    }
  }
}
<|endoftext|>