text:
/*
  Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License, version 2.0,
  as published by the Free Software Foundation.

  This program is also distributed with certain software (including
  but not limited to OpenSSL) that is licensed under separate terms,
  as designated in a particular file or component or in included license
  documentation.  The authors of MySQL hereby grant you an additional
  permission to link the program and your derivative works with the
  separately licensed software that they have included with MySQL.

  This program 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, version 2.0, for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
*/

#ifndef UNITTEST_OBJECT_FILTER_PARSER
#include "client/dump/object_filter.h"

#include "client/dump/database.h"
#include "client/dump/event_scheduler_event.h"
#include "client/dump/mysql_function.h"
#include "client/dump/pattern_matcher.h"
#include "client/dump/privilege.h"
#include "client/dump/stored_procedure.h"
#include "client/dump/table.h"
#include "client/dump/trigger.h"
#endif
#include <stddef.h>
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>

using std::placeholders::_1;

std::string parse_inclusion_string(
    std::string val, std::vector<std::pair<std::string, std::string>> &list,
    bool allow_schema, bool is_user_object) {
  try {
    typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer_t;
    typedef boost::tokenizer<boost::escaped_list_separator<char>>::iterator
        titerator_t;
    typedef boost::escaped_list_separator<char> separator_t;

    const separator_t sep_csl('\\', ',', '\"');
    const separator_t sep_user('\\', '@', '\"');
    const separator_t sep_object('\\', '.', '\'');
    const separator_t *sep = is_user_object ? &sep_user : &sep_object;

    tokenizer_t outer_tok(val, sep_csl);
    for (titerator_t it = outer_tok.begin(); it != outer_tok.end(); it++) {
      std::string elt = *it;
      boost::trim(elt);
      tokenizer_t itok(elt, *sep);
      std::vector<std::string> object_parts;
      for (titerator_t iit = itok.begin(); iit != itok.end(); iit++) {
        std::string s = *iit;
        boost::trim(s);
        if (s.length() == 0)
          return "empty object element specified (\"" + *it + "\")";
        if (is_user_object)
          object_parts.push_back(("'" + s + "'"));
        else
          object_parts.push_back(s);
      }

      if (object_parts.size() == 1) {
        if (is_user_object)
          list.push_back(std::make_pair(object_parts[0], "%"));
        else
          list.push_back(std::make_pair("%", object_parts[0]));
      } else if (object_parts.size() == 2 && (allow_schema || is_user_object)) {
        list.push_back(std::make_pair(object_parts[0], object_parts[1]));
      } else
        return "Invalid object name specified (\"" + *it + "\")";
    }
  } catch (std::exception const &ex) {
    return ex.what();
  } catch (...) {
    return "unknown exception";
  }
  return "";
}

#ifndef UNITTEST_OBJECT_FILTER_PARSER
using namespace Mysql::Tools::Dump;

void Object_filter::process_object_inclusion_string(
    std::vector<std::pair<std::string, std::string>> &list,
    bool allow_schema /*= true*/, bool is_user_object) {
  std::string err;
  err = parse_inclusion_string(m_include_tmp_string.value(), list, allow_schema,
                               is_user_object);
  if (err.length() > 0)
    m_program->error(Mysql::Tools::Base::Message_data(
        1,
        "Failed to parse --include -<type> or"
        "--exclude-<type> argument \"" +
            m_include_tmp_string.value() + "\": " + err,
        Mysql::Tools::Base::Message_type_error));
}

void Object_filter::exclude_events_callback(char *) {
  this->process_object_inclusion_string(m_events_excluded);
}

void Object_filter::include_events_callback(char *) {
  this->process_object_inclusion_string(m_events_included);
}

void Object_filter::exclude_triggers_callback(char *) {
  this->process_object_inclusion_string(m_triggers_excluded);
}

void Object_filter::include_triggers_callback(char *) {
  this->process_object_inclusion_string(m_triggers_included);
}

void Object_filter::exclude_routines_callback(char *) {
  this->process_object_inclusion_string(m_routines_excluded);
}

void Object_filter::include_routines_callback(char *) {
  this->process_object_inclusion_string(m_routines_included);
}

void Object_filter::exclude_tables_callback(char *) {
  this->process_object_inclusion_string(m_tables_excluded);
}

void Object_filter::include_tables_callback(char *) {
  this->process_object_inclusion_string(m_tables_included);
}

void Object_filter::exclude_databases_callback(char *) {
  this->process_object_inclusion_string(m_databases_excluded, false);
}

void Object_filter::include_databases_callback(char *) {
  this->process_object_inclusion_string(m_databases_included, false);
}

void Object_filter::include_users_callback(char *) {
  this->process_object_inclusion_string(m_users_included, false, true);
}

void Object_filter::exclude_users_callback(char *) {
  this->process_object_inclusion_string(m_users_excluded, false, true);
}

bool Object_filter::is_user_included_by_lists(
    const std::string &user_name,
    std::vector<std::pair<std::string, std::string>> *include_list,
    std::vector<std::pair<std::string, std::string>> *exclude_list) {
  size_t separator_idx = user_name.find('@');
  return is_object_included_by_lists(user_name.substr(0, separator_idx),
                                     user_name.substr(separator_idx + 1),
                                     include_list, exclude_list);
}

bool Object_filter::is_object_included_by_lists(
    const std::string &schema_name, const std::string &object_name,
    std::vector<std::pair<std::string, std::string>> *include_list,
    std::vector<std::pair<std::string, std::string>> *exclude_list) {
  using Detail::Pattern_matcher;

  if (include_list->size() == 0 && exclude_list->size() == 0) return true;

  bool is_included = false;
  bool is_excluded = false;

  if (m_databases_included.size() == 0 && m_databases_excluded.size() == 0)
    return true;

  for (std::vector<std::pair<std::string, std::string>>::iterator it =
           include_list->begin();
       it != include_list->end(); ++it)
    is_included |=
        Pattern_matcher::is_pattern_matched(schema_name, it->first) &&
        Pattern_matcher::is_pattern_matched(object_name, it->second);
  for (std::vector<std::pair<std::string, std::string>>::iterator it =
           exclude_list->begin();
       it != exclude_list->end(); ++it)
    is_excluded |=
        Pattern_matcher::is_pattern_matched(schema_name, it->first) &&
        Pattern_matcher::is_pattern_matched(object_name, it->second);

  return (exclude_list->size() > 0)
             ? (!is_excluded || (is_included && is_excluded))
             : is_included;
}

bool Object_filter::is_object_included_in_dump(Abstract_data_object *object) {
  if (object == nullptr) return true;
  if (dynamic_cast<Database *>(object) == nullptr &&
      dynamic_cast<Privilege *>(object) == nullptr) {
    /*
      All objects except database/event/users need to check for schema
      inclusion rules.
      */
    if (object->get_schema().size() > 0 &&
        !is_object_included_by_lists("", object->get_schema(),
                                     &m_databases_included,
                                     &m_databases_excluded))
      return false;
  }
  std::vector<std::pair<std::string, std::string>> *include_list;
  std::vector<std::pair<std::string, std::string>> *exclude_list;
  bool *dump_switch = nullptr;

  if (dynamic_cast<Table *>(object) != nullptr) {
    include_list = &m_tables_included;
    exclude_list = &m_tables_excluded;
  } else if (dynamic_cast<Database *>(object) != nullptr) {
    include_list = &m_databases_included;
    exclude_list = &m_databases_excluded;
  } else if (dynamic_cast<Stored_procedure *>(object) != nullptr ||
             dynamic_cast<Mysql_function *>(object) != nullptr) {
    include_list = &m_routines_included;
    exclude_list = &m_routines_excluded;
    dump_switch = &m_dump_routines;
  } else if (dynamic_cast<Trigger *>(object) != nullptr) {
    /*
      Check if table on which this trigger is defined is in
      excluded list
    */
    Trigger *tmp_trigger = dynamic_cast<Trigger *>(object);
    const Table *defined_table = tmp_trigger->get_defined_table();
    if (defined_table) {
      include_list = &m_tables_included;
      exclude_list = &m_tables_excluded;
      if (!is_object_included_by_lists(defined_table->get_schema(),
                                       defined_table->get_name(), include_list,
                                       exclude_list))
        return false;
    }
    include_list = &m_triggers_included;
    exclude_list = &m_triggers_excluded;
    dump_switch = &m_dump_triggers;
  } else if (dynamic_cast<Event_scheduler_event *>(object) != nullptr) {
    include_list = &m_events_included;
    exclude_list = &m_events_excluded;
    dump_switch = &m_dump_events;
  } else if (dynamic_cast<Privilege *>(object) != nullptr) {
    if (m_dump_users || m_users_included.size() > 0 ||
        m_users_excluded.size() > 0) {
      include_list = &m_users_included;
      exclude_list = &m_users_excluded;
      return is_user_included_by_lists(object->get_name(), include_list,
                                       exclude_list);
    }
    return false;
  } else
    return true;

  return (dump_switch == nullptr || *dump_switch) &&
         is_object_included_by_lists(object->get_schema(), object->get_name(),
                                     include_list, exclude_list);
}

void Object_filter::create_options() {
  this->create_new_option(&m_include_tmp_string, "include-databases",
                          "Specifies comma-separated list of databases and all "
                          "of its objects to "
                          "include. If there are no exclusions then only "
                          "included objects will be "
                          "dumped. Otherwise all objects that are not on "
                          "exclusion lists or are "
                          "on inclusion list will be dumped.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::include_databases_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "exclude-databases",
          "Specifies comma-separated list of databases to exclude.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::exclude_databases_callback, this, _1)));
  this->create_new_option(&m_include_tmp_string, "include-tables",
                          "Specifies comma-separated list of tables to "
                          "include. If there is no exclusions then only "
                          "included objects will be "
                          "dumped. Otherwise all objects that are not on "
                          "exclusion lists or are "
                          "on inclusion list will be dumped.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::include_tables_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "exclude-tables",
          "Specifies comma-separated list of tables to exclude.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::exclude_tables_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "include-routines",
          "Specifies comma-separated list of stored procedures or functions to "
          "include. If there is no exclusions then only included objects will "
          "be "
          "dumped. Otherwise all objects that are not on exclusion lists or "
          "are "
          "on inclusion list will be dumped.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::include_routines_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "exclude-routines",
          "Specifies comma-separated list of stored procedures or functions to "
          "exclude.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::exclude_routines_callback, this, _1)));
  this->create_new_option(&m_include_tmp_string, "include-triggers",
                          "Specifies comma-separated list of triggers to "
                          "include. If there is no exclusions then only "
                          "included objects will be "
                          "dumped. Otherwise all objects that are not on "
                          "exclusion lists or are "
                          "on inclusion list will be dumped.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::include_triggers_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "exclude-triggers",
          "Specifies comma-separated list of triggers to exclude.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::exclude_triggers_callback, this, _1)));
  this->create_new_option(&m_include_tmp_string, "include-events",
                          "Specifies comma-separated list of events to "
                          "include. If there is no exclusions then only "
                          "included objects will be "
                          "dumped. Otherwise all objects that are not on "
                          "exclusion lists or are "
                          "on inclusion list will be dumped.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::include_events_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "exclude-events",
          "Specifies comma-separated list of events to exclude.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::exclude_events_callback, this, _1)));
  this->create_new_option(&m_dump_routines, "routines",
                          "Dump stored procedures and functions.")
      ->set_value(true);
  this->create_new_option(&m_dump_triggers, "triggers", "Dump triggers.")
      ->set_value(true);
  this->create_new_option(&m_dump_events, "events",
                          "Dump event scheduler events.")
      ->set_value(true);
  this->create_new_option(&m_dump_users, "users",
                          "Dump users with their privileges in GRANT format. "
                          "Disabled by default.")
      ->set_value(false);
  this->create_new_option(&m_include_tmp_string, "include-users",
                          "Specifies comma-separated list of users to "
                          "include. If there is no exclusions then only "
                          "included objects will be "
                          "dumped. Otherwise all objects that are not on "
                          "exclusion lists or are "
                          "on inclusion list will be dumped.")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::include_users_callback, this, _1)));
  this->create_new_option(
          &m_include_tmp_string, "exclude-users",
          "Specifies comma-separated list of users to exclude. ")
      ->add_callback(new std::function<void(char *)>(
          std::bind(&Object_filter::exclude_users_callback, this, _1)));
}

Object_filter::Object_filter(Mysql::Tools::Base::Abstract_program *program)
    : m_program(program) {}
#endif /* UNITTEST_OBJECT_FILTER_PARSER */

ext: cc


text:
//  Boost string_algo library classification.hpp header file  ---------------------------//

//  Copyright Pavol Droba 2002-2003. Use, modification and
//  distribution is subject to 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)

//  See http://www.boost.org for updates, documentation, and revision history.

#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP

#include <boost/algorithm/string/config.hpp>
#include <algorithm>
#include <functional>
#include <locale>
#include <set>

#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>

#include <boost/algorithm/string/predicate_facade.hpp>
#include <boost/type_traits/remove_const.hpp>

namespace boost {
    namespace algorithm {
        namespace detail {

//  classification functors -----------------------------------------------//

            // is_classified functor
            struct is_classifiedF :
                public predicate_facade<is_classifiedF>
            {
                // Boost.Lambda support
                template <class Args> struct sig { typedef bool type; };

                // Constructor from a locale
                is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
                    m_Type(Type), m_Locale(Loc) {}

                // Operation
                template<typename CharT>
                bool operator()( CharT Ch ) const
                {
                    return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
                }

                #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL)
                    template<>
                    bool operator()( char const Ch ) const
                    {
                        return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
                    }
                #endif

            private:
                const std::ctype_base::mask m_Type;
                const std::locale m_Locale;
            };

            // is_any_of functor
            /*
                returns true if the value is from the specified set
            */
            template<typename CharT>
            struct is_any_ofF :
                public predicate_facade<is_any_ofF<CharT> >
            {
                // Boost.Lambda support
                template <class Args> struct sig { typedef bool type; };

                // Constructor
                template<typename RangeT>
                is_any_ofF( const RangeT& Range ) :
                    m_Set( begin(Range), end(Range) ) {}

                // Operation
                template<typename Char2T>
                bool operator()( Char2T Ch ) const
                {
                    return m_Set.find(Ch)!=m_Set.end();
                }

            private:
                // set cannot operate on const value-type
                typedef typename remove_const<CharT>::type set_value_type;
                std::set<set_value_type> m_Set;
            };

            // is_from_range functor
            /*
                returns true if the value is from the specified range.
                (i.e. x>=From && x>=To)
            */
            template<typename CharT>
            struct is_from_rangeF :
                public predicate_facade< is_from_rangeF<CharT> >
            {
                // Boost.Lambda support
                template <class Args> struct sig { typedef bool type; };

                // Constructor
                is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}

                // Operation
                template<typename Char2T>
                bool operator()( Char2T Ch ) const
                {
                    return ( m_From <= Ch ) && ( Ch <= m_To );
                }

            private:
                CharT m_From;
                CharT m_To;
            };

            // class_and composition predicate
            template<typename Pred1T, typename Pred2T>
            struct pred_andF :
                public predicate_facade< pred_andF<Pred1T,Pred2T> >
            {
            public:

                // Boost.Lambda support
                template <class Args> struct sig { typedef bool type; };

                // Constructor
                pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
                    m_Pred1(Pred1), m_Pred2(Pred2) {}

                // Operation
                template<typename CharT>
                bool operator()( CharT Ch ) const
                {
                    return m_Pred1(Ch) && m_Pred2(Ch);
                }

            private:
                Pred1T m_Pred1;
                Pred2T m_Pred2;
            };

            // class_or composition predicate
            template<typename Pred1T, typename Pred2T>
            struct pred_orF :
                public predicate_facade< pred_orF<Pred1T,Pred2T> >
            {
            public:
                // Boost.Lambda support
                template <class Args> struct sig { typedef bool type; };

                // Constructor
                pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
                    m_Pred1(Pred1), m_Pred2(Pred2) {}

                // Operation
                template<typename CharT>
                bool operator()( CharT Ch ) const
                {
                    return m_Pred1(Ch) || m_Pred2(Ch);
                }

            private:
                Pred1T m_Pred1;
                Pred2T m_Pred2;
            };

            // class_not composition predicate
            template< typename PredT >
            struct pred_notF :
                public predicate_facade< pred_notF<PredT> >
            {
            public:
                // Boost.Lambda support
                template <class Args> struct sig { typedef bool type; };

                // Constructor
                pred_notF( PredT Pred ) : m_Pred(Pred) {}

                // Operation
                template<typename CharT>
                bool operator()( CharT Ch ) const
                {
                    return !m_Pred(Ch);
                }

            private:
                PredT m_Pred;
            };

        } // namespace detail
    } // namespace algorithm
} // namespace boost

#endif  // BOOST_STRING_CLASSIFICATION_DETAIL_HPP

ext: hpp

max_stars_repo_name: dstrigl/mcotf

max_issues_repo_name: dstrigl/mcotf

max_forks_repo_name: dstrigl/mcotf


text:
#include "FileFinder.h"

#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
#include <fstream>
#include <codecvt>

static void wstr_tolower(std::wstring& text)
{
	std::use_facet<std::ctype<wchar_t> >(std::locale()).tolower(&text[0], &text[0] + text.size());
}

FileFinder::FileFinder(const std::wstring& text, bool ignoreCase)
	: m_text(text), m_ignoreCase(ignoreCase)
{
	if (ignoreCase) wstr_tolower(m_text);
}

bool FileFinder::search(const std::wstring& path)
{
#ifdef _WINDOWS
	std::wifstream wif(path);
#else
	std::wifstream wif(WC2MB(path));
#endif
	static std::locale locale_ru = std::locale("ru_RU.UTF-8");
	wif.imbue(std::locale(std::locale(), new std::codecvt_utf8<wchar_t>));
	const size_t text_len = m_text.length();
	const size_t buf_size = 8192;
	wchar_t buf[buf_size];
	size_t offset = 0;
	while (true) {
		wif.read(buf + offset, buf_size - offset);
		auto read = wif.gcount();
		if (read == 0) return false;
		wchar_t* end = buf + offset + read;
		if (m_ignoreCase) std::use_facet<std::ctype<wchar_t> >(locale_ru).tolower(buf + offset, end);
		auto it = std::search(buf, end, m_text.begin(), m_text.end());
		if (it != end) return true;
		offset = text_len;
		std::memmove(buf, end - offset, offset * sizeof(wchar_t));
	}
}

#ifdef _WINDOWS

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

std::string time2str(FILETIME& time) {
	SYSTEMTIME st;
	FileTimeToSystemTime(&time, &st);
	char* format = "%d-%02d-%02dT%02d:%02d:%02d.%03dZ";
	char buffer[255];
	wsprintfA(buffer,
		format,
		st.wYear,
		st.wMonth,
		st.wDay,
		st.wHour,
		st.wMinute,
		st.wSecond,
		st.wMilliseconds);
	return buffer;
}

void FileFinder::files(const std::wstring& root, const std::wstring& mask)
{
	std::wstring tmp = root + L"\\" + mask;
	WIN32_FIND_DATA file;
	HANDLE hFind = FindFirstFileEx(tmp.c_str(), FindExInfoStandard, &file, FindExSearchNameMatch, NULL, 0);
	if (hFind == INVALID_HANDLE_VALUE) return;
	do {
		if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
		std::wstring path = root + L"\\" + std::wstring(file.cFileName);
		if (m_text.empty() || search(path)) {
			nlohmann::json j;
			j["path"] = WC2MB(path);
			j["name"] = WC2MB(file.cFileName);
			j["size"] = (static_cast<ULONGLONG>(file.nFileSizeHigh) << sizeof(file.nFileSizeLow) * 8) | file.nFileSizeLow;
			j["date"] = time2str(file.ftLastWriteTime);
			m_json.push_back(j);
		}
	} while (FindNextFileW(hFind, &file));
	FindClose(hFind);
}

void FileFinder::dirs(const std::wstring& root, const std::wstring& mask)
{
	files(root, mask);
	std::wstring tmp = root + L"\\*";
	WIN32_FIND_DATA file;
	HANDLE hFind = FindFirstFileEx(tmp.c_str(), FindExInfoStandard, &file, FindExSearchNameMatch, NULL, 0);
	if (hFind == INVALID_HANDLE_VALUE) return;
	do {
		if (file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			if (lstrcmpW(file.cFileName, L".") == 0) continue;
			if (lstrcmpW(file.cFileName, L"..") == 0) continue;
			std::wstring path = root + L"\\" + std::wstring(file.cFileName);
			dirs(path, mask);
		}
	} while (FindNextFileW(hFind, &file));
	FindClose(hFind);
}

std::wstring FileFinder::find(const std::wstring& path, const std::wstring& mask)
{
	dirs(path, mask);
	return MB2WC(m_json.dump());
}

#else //_WINDOWS

#ifdef USE_BOOST

#include <boost/regex.hpp>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/replace.hpp>

static void EscapeRegex(std::wstring& regex)
{
	// Escape all regex special chars
	boost::replace_all(regex, "\\", "\\\\");
	boost::replace_all(regex, "^", "\\^");
	boost::replace_all(regex, ".", "\\.");
	boost::replace_all(regex, "$", "\\$");
	boost::replace_all(regex, "|", "\\|");
	boost::replace_all(regex, "(", "\\(");
	boost::replace_all(regex, ")", "\\)");
	boost::replace_all(regex, "{", "\\{");
	boost::replace_all(regex, "{", "\\}");
	boost::replace_all(regex, "[", "\\[");
	boost::replace_all(regex, "]", "\\]");
	boost::replace_all(regex, "*", "\\*");
	boost::replace_all(regex, "+", "\\+");
	boost::replace_all(regex, "?", "\\?");
	boost::replace_all(regex, "/", "\\/");

	// Convert chars '*?' back to their regex equivalents
	boost::replace_all(regex, "\\?", ".");
	boost::replace_all(regex, "\\*", ".*");
}

#include <unistd.h>
#include <sys/stat.h>

static std::string time2str(time_t t)
{
	struct tm lt;
	localtime_r(&t, &lt);
	char buffer[80];
	strftime(buffer, sizeof(buffer), "%FT%T", &lt);
	return buffer;
}

void FileFinder::dirs(const std::wstring& root, const std::wstring& mask)
{
	boost::wregex pattern(mask, m_ignoreCase ? boost::regex::icase : boost::regex::normal);
	boost::filesystem::recursive_directory_iterator end_itr; // Default ctor yields past-the-end
	for (boost::filesystem::recursive_directory_iterator i(root); i != end_itr; ++i) {
		if (boost::filesystem::is_regular_file(i->status())) {
			boost::wsmatch what;
			std::wstring filepath = i->path().wstring();
			std::wstring filename = i->path().filename().wstring();
			if (!boost::regex_match(filename, what, pattern)) continue;
			if (m_text.empty() || search(i->path().wstring())) {
				nlohmann::json j;
				j["path"] = WC2MB(filepath);
				j["name"] = WC2MB(filename);
				j["size"] = (int32_t)boost::filesystem::file_size(filepath);
				j["date"] = time2str(boost::filesystem::last_write_time(filepath));
				m_json.push_back(j);
			}
		}
	}
}

std::wstring FileFinder::find(const std::wstring& path, const std::wstring& mask)
{
	std::wstring regex = mask;
	EscapeRegex(regex);
	dirs(path, L"^" + regex + L"$");
	return MB2WC(m_json.dump());
}

#else //USE_BOOST

std::wstring FileFinder::find(const std::wstring& path, const std::wstring& mask) { return {}; }

void FileFinder::dirs(const std::wstring& root, const std::wstring& mask) {}

#endif //USE_BOOST

void FileFinder::files(const std::wstring& root, const std::wstring& mask) {}

#endif //_WINDOWS

ext: cpp


text:
/*
	Copyright (C) 2003-2013 by David White <davewx7@gmail.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <set>
#include <stack>
#include <string>

#include <boost/bind.hpp>

#include <stdio.h>

#include "asserts.hpp"
#include "foreach.hpp"
#include "formula_object.hpp"
#include "json_parser.hpp"
#include "variant_utils.hpp"
#include "wml_formula_callable.hpp"

#ifdef _MSC_VER
#define strtoll _strtoui64
#endif

namespace game_logic
{

namespace {
struct scope_info {
	std::set<const_wml_serializable_formula_callable_ptr> objects_to_write, objects_written;
};

std::stack<scope_info, std::vector<scope_info> > scopes;

std::map<std::string, std::function<variant(variant)> >& type_registry() {
	static std::map<std::string, std::function<variant(variant)> > instance;
	return instance;
}

}

int wml_serializable_formula_callable::register_serializable_type(const char* name, std::function<variant(variant)> ctor)
{

	std::string key(name);
	type_registry()[key] = ctor;
	return type_registry().size();
}

bool wml_serializable_formula_callable::deserialize_obj(const variant& var, variant* target)
{
	for(const std::pair<std::string, std::function<variant(variant)> >& p : type_registry()) {
		if(var.has_key(p.first)) {
			*target = p.second(var);
			return true;
		}
	}

	return false;
}

const std::map<std::string, std::function<variant(variant)> >& wml_serializable_formula_callable::registered_types()
{
	return type_registry();
}

variant wml_serializable_formula_callable::write_to_wml() const
{
	variant result = serialize_to_wml();
	char addr_buf[256];
	sprintf(addr_buf, "%p", this);
	result.add_attr(variant("_addr"), variant(addr_buf));
	return result;
}

void wml_formula_callable_serialization_scope::register_serialized_object(const_wml_serializable_formula_callable_ptr ptr)
{
	ASSERT_LOG(scopes.empty() == false, "register_serialized_object() called when there is no wml_formula_callable_serialization_scope");
	scopes.top().objects_written.insert(ptr);
}

bool wml_formula_callable_serialization_scope::is_active()
{
	return scopes.empty() == false;
}

wml_formula_callable_serialization_scope::wml_formula_callable_serialization_scope()
{
	scopes.push(scope_info());
}

wml_formula_callable_serialization_scope::~wml_formula_callable_serialization_scope()
{
	scopes.pop();
}

namespace {
void add_object_to_set(variant v, std::set<wml_serializable_formula_callable*>* set, std::set<std::string>* already_recorded) {
	if(v.is_map()) {
		variant addr = v["_addr"];
		if(addr.is_string()) {
			already_recorded->insert(addr.as_string());
		}

		return;
	}

	if(!v.is_callable()) {
		return;
	}

	wml_serializable_formula_callable* ptr = v.try_convert<wml_serializable_formula_callable>();
	if(ptr) {
		set->insert(ptr);
		wml_formula_callable_serialization_scope::register_serialized_object(ptr);
	}
}
}

variant wml_formula_callable_serialization_scope::write_objects(variant obj, int* num_objects) const
{
	std::map<variant, variant> res;
	std::set<wml_serializable_formula_callable*> objects;
	std::set<std::string> already_known;
	game_logic::formula_object::visit_variants(obj, boost::bind(add_object_to_set, _1, &objects, &already_known));

	std::vector<variant> results_list;
	foreach(wml_serializable_formula_callable* item, objects) {
		char addr_buf[256];
		sprintf(addr_buf, "%p", item);
		std::string key(addr_buf);
		if(already_known.count(key)) {
			continue;
		}

		results_list.push_back(item->write_to_wml());
	}

	if(num_objects) {
		*num_objects = objects.size();
	}

	res[variant("character")] = variant(&results_list);

	return variant(&res);
}

namespace {
std::map<intptr_t, wml_serializable_formula_callable_ptr> registered_objects;
}

void wml_formula_callable_read_scope::register_serialized_object(intptr_t addr, wml_serializable_formula_callable_ptr ptr)
{
	//fprintf(stderr, "REGISTER SERIALIZED: 0x%x\n", (int)addr);
	if(ptr.get() != NULL) {
		registered_objects[addr] = ptr;
	}
}

wml_serializable_formula_callable_ptr wml_formula_callable_read_scope::get_serialized_object(intptr_t addr)
{
	auto itor = registered_objects.find(addr);
	if(itor != registered_objects.end()) {
		return itor->second;
	} else {
		return wml_serializable_formula_callable_ptr();
	}
}

namespace {
int g_nformula_callable_read_scope = 0;
}

wml_formula_callable_read_scope::wml_formula_callable_read_scope()
{
	++g_nformula_callable_read_scope;
}

wml_formula_callable_read_scope::~wml_formula_callable_read_scope()
{
	std::set<variant*> v;
	std::set<variant*> unfound_variants;
	swap_variants_loading(v);
	for(std::set<variant*>::iterator i = v.begin(); i != v.end(); ++i) {
		variant& var = **i;
		//fprintf(stderr, "LOAD SERIALIZED: 0x%x\n", (int)var.as_callable_loading());
		auto itor = registered_objects.find(var.as_callable_loading());
		if(itor == registered_objects.end()) {
			unfound_variants.insert(*i);
		} else {
			var = variant(itor->second.get());
		}
	}

	if(unfound_variants.empty()) {
		variant::resolve_delayed();
	} else {
		swap_variants_loading(unfound_variants);
	}

	if(--g_nformula_callable_read_scope == 0) {
		registered_objects.clear();
	}
}

bool wml_formula_callable_read_scope::try_load_object(intptr_t id, variant& v)
{
	std::map<intptr_t, wml_serializable_formula_callable_ptr>::const_iterator itor = registered_objects.find(id);
	if(itor != registered_objects.end()) {
		v = variant(itor->second.get());
		return true;
	} else {
		return false;
	}
}

variant serialize_doc_with_objects(variant v)
{
	variant orig = v;
	if(!v.is_map()) {
		std::map<variant,variant> m;
		m[variant("__serialized_doc")] = v;
		v = variant(&m);
	}
	game_logic::wml_formula_callable_serialization_scope serialization_scope;
	int num_objects = 0;
	variant serialized_objects = serialization_scope.write_objects(v, &num_objects);
	if(num_objects == 0) {
		return orig;
	}
	v.add_attr(variant("serialized_objects"), serialized_objects);
	return v;
}

namespace {

variant deserialize_doc_with_objects_internal(const std::string& msg, bool fname)
{
	variant v;
	{
		const game_logic::wml_formula_callable_read_scope read_scope;

		if(fname) {
			v = json::parse_from_file(msg);
		} else {
			try {
				v = json::parse(msg);
			} catch(json::parse_error& e) {
				ASSERT_LOG(false, "ERROR PROCESSING FSON: --BEGIN--" << msg << "--END-- ERROR: " << e.error_message());
			}
		}

		if(v.is_map() && v.has_key(variant("serialized_objects"))) {
			foreach(variant obj_node, v["serialized_objects"]["character"].as_list()) {
				game_logic::wml_serializable_formula_callable_ptr obj = obj_node.try_convert<game_logic::wml_serializable_formula_callable>();
				ASSERT_LOG(obj.get() != NULL, "ILLEGAL OBJECT FOUND IN SERIALIZATION");
				std::string addr_str = obj->addr();
				if(addr_str.size() > 15) {
					addr_str.resize(15);
				}
				const intptr_t addr_id = strtoll(addr_str.c_str(), NULL, 16);

				game_logic::wml_formula_callable_read_scope::register_serialized_object(addr_id, obj);
			}

			v.remove_attr_mutation(variant("serialized_objects"));
		}
	}

	if(v.is_map() && v.has_key(variant("__serialized_doc"))) {
		return v["__serialized_doc"];
	}

	return v;
}

}

variant deserialize_doc_with_objects(const std::string& msg)
{
	return deserialize_doc_with_objects_internal(msg, false);
}

variant deserialize_file_with_objects(const std::string& fname)
{
	return deserialize_doc_with_objects_internal(fname, true);
}

}

max_stars_repo_name: sweetkristas/anura

max_issues_repo_name: sweetkristas/anura

max_forks_repo_name: sweetkristas/anura


text:
#include "clipboard.h"

#include "orz/geom.h"

#include <wx/image.h>
#include <wx/clipbrd.h>
#include <boost/scoped_array.hpp>

namespace App
{
	using namespace Geom;

	bool ImageToClipboard(std::shared_ptr<Img::Image> source, Img::Properties props)
	{
		if (!source.get()) return false;
		if (source->IsFinished() == false) return false;

		Geom::SizeInt size(source->GetSize());
		Img::Surface::Ptr surface = source->CurrentSurface();
		if (surface == 0)
			return false;

		// Signal an error here
		if (wxTheClipboard->Open())
		{
			unsigned char* rgb = nullptr;
			unsigned char* alpha = nullptr;
			try
			{
				// TODO: Handle rotation
				rgb = (unsigned char*)malloc(size.Width * size.Height * 3);
				if (HasAlpha(surface->GetFormat()))
				{
					alpha = (unsigned char*)malloc(size.Width * size.Height);
				}

				auto prgb = rgb;
				auto palpha = alpha;

				// wxWidgets wants the data split into RGB and alpha. This isn't very efficient, but not much to do other than hacking wxWidgets
				boost::scoped_array<uint8_t> pBuf(new uint8_t[size.Width * 4]);
				for (auto y = 0; y < size.Height; y++) {
					auto iidx = 0;
					surface->CopyRectToBuffer(
						pBuf.get(),
						size.Width * 4,
						RectInt(PointInt(0, y), SizeInt(size.Width, 1)),
						props.BackgroundColor,
						props.Brightness,
						props.Contrast,
						props.Gamma, false);
					for (auto x = 0; x < size.Width; x++)
					{
						auto r = pBuf[iidx++];
						auto g = pBuf[iidx++];
						auto b = pBuf[iidx++];
						auto a = pBuf[iidx++];
						*prgb++ = b;
						*prgb++ = g;
						*prgb++ = r;
						if (palpha != nullptr)
						{
							*palpha++ = a;
						}
					}
				}
				wxImage img({ size.Width, size.Height }, rgb, alpha, false);
				rgb = nullptr;
				alpha = nullptr;

				wxTheClipboard->SetData(new wxBitmapDataObject(img));

			}
			catch (...)
			{
				wxTheClipboard->Close();
				if (rgb != nullptr)
				{
					free(rgb);
				}
				if (alpha != nullptr)
				{
					free(alpha);
				}
				throw;
			}

			wxTheClipboard->Close();
		}
		return true;
	}
}

max_stars_repo_name: poppeman/Pictus

max_issues_repo_name: poppeman/Pictus

max_forks_repo_name: poppeman/Pictus


text:
// Copyright 2018 Your Name <your_email>

#ifndef INCLUDE_HEADER_HPP_
#define INCLUDE_HEADER_HPP_
#include <iostream>
#include <boost/thread.hpp>
#include <boost/asio.hpp>
#include <chrono>
#include <thread>
#include "boost/date_time/posix_time/posix_time.hpp"
#include <vector>
#include <mutex>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <cstring>
#include <string>

#define SIZE_FILE 10 * 1024 * 1024
#define TIME_OUT 5000
#define PORT_NUM 8001
#define SECONDS 1

const char PWD[] = "/home/darioshka/Desktop/my_file%N.log";
const char ATTR_NAME[] = "Severity";
const char type_exeption[] = "read_until: Resource temporarily unavailable";
const char START[] = "server started...";
const char STR[] = "127.0.0.1";
const char CONNECTED[] = "client connected ";
const char PING_OK[] = "ping ok\n";
const char LIST_CHANED[] = "client list chaned\n";
const char LOGIN_OK[] = "login ok\n";
const char LOGIN[] = "login";
const char PING[] = "ping";
const char CLIENTS[] = "clients";
const char OUTPUT_FORMAT[] = "[%TimeStamp%] [%Severity%] %Message%";

using sock = boost::asio::ip::tcp::socket;
using endpoint = boost::asio::ip::tcp::endpoint;
using acceptor = boost::asio::ip::tcp::acceptor;
using io_context = boost::asio::io_context;
using input_ip = boost::asio::ip::address;
using std::int64_t;
io_context context;
std::mutex mutex;

struct talk_to_client{
private:
    std::string answ;
    sock sock_;
    std::string username_;
    boost::posix_time::ptime last_ping;
    bool client_list_chaned = true;

public:
    talk_to_client();
    sock &my_socket();
    std::string &username();
    bool &list_chaned();
    void write(const std::string &msg);
    void read_answer();
    void login(std::string msg);
    void ping();
    void client_list();
    void process_request();
    bool timed_out() const;
    void stop();
};
std::vector<std::shared_ptr<talk_to_client>> clients;

#endif // INCLUDE_HEADER_HPP_


text:
//=======================================================================
// Copyright (c)
//
// 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 read_dist.hpp
 * @brief
 * @author Jakub Oćwieja
 * @version 1.0
 * @date 2014-05-19
 */

#ifndef PAAL_READ_DIST_HPP
#define PAAL_READ_DIST_HPP

#include "paal/utils/irange.hpp"

#include <boost/graph/adjacency_list.hpp>

#include <cassert>

namespace paal {
namespace {

typedef  boost::adjacency_list<
        boost::vecS,
        boost::vecS,
        boost::undirectedS,
        boost::no_property,
        boost::property < boost::edge_weight_t, int> >
    Graph;

Graph read_dist(std::istream& ist) {
    assert(ist.good());

    int n, m; ist >> n >> m;
    std::vector< std::pair<int, int> > edges(m);
    std::vector< int > edgeWeights(m);

    for (auto i: paal::irange(m)) {
        ist >> edges[i].first >> edges[i].second >> edgeWeights[i];
    }

    return Graph(edges.begin(), edges.end(), edgeWeights.begin(), n);
}

}
} // paal

#endif // PAAL_READ_DIST_HPP

max_stars_repo_name: Kommeren/AA

max_issues_repo_name: Kommeren/AA

max_forks_repo_name: Kommeren/AA


text:
/*
 *          Copyright Andrey Semashev 2007 - 2015.
 * 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   form_named_scope.cpp
 * \author Andrey Semashev
 * \date   07.02.2009
 *
 * \brief  This header contains tests for the \c named_scope formatter.
 */

#define BOOST_TEST_MODULE form_named_scope

#include <string>
#include <boost/config.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/log/attributes/constant.hpp>
#include <boost/log/attributes/attribute_set.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/formatting_ostream.hpp>
#include <boost/log/utility/string_literal.hpp>
#include <boost/log/core/record.hpp>
#include "char_definitions.hpp"
#include "make_record.hpp"

namespace logging = boost::log;
namespace attrs = logging::attributes;
namespace expr = logging::expressions;
namespace keywords = logging::keywords;

namespace {

    template< typename CharT >
    struct named_scope_test_data;

    struct named_scope_test_data_base
    {
        static logging::string_literal scope1() { return logging::str_literal("scope1"); }
        static logging::string_literal scope2() { return logging::str_literal("scope2"); }

        static logging::string_literal file() { return logging::str_literal(__FILE__); }
        static logging::string_literal posix_file() { return logging::str_literal("/home/user/posix_file.cpp"); }
        static logging::string_literal windows_file1() { return logging::str_literal("C:\\user\\windows_file1.cpp"); }
        static logging::string_literal windows_file2() { return logging::str_literal("C:/user/windows_file2.cpp"); }
    };

#ifdef BOOST_LOG_USE_CHAR
    template< >
    struct named_scope_test_data< char > :
        public test_data< char >,
        public named_scope_test_data_base
    {
        static logging::string_literal default_format() { return logging::str_literal("%n"); }
        static logging::string_literal full_format() { return logging::str_literal("%n (%f:%l)"); }
        static logging::string_literal short_filename_format() { return logging::str_literal("%n (%F:%l)"); }
        static logging::string_literal scope_function_name_format() { return logging::str_literal("%c"); }
        static logging::string_literal function_name_format() { return logging::str_literal("%C"); }
        static logging::string_literal delimiter1() { return logging::str_literal("|"); }
        static logging::string_literal incomplete_marker() { return logging::str_literal("<<and more>>"); }
        static logging::string_literal empty_marker() { return logging::str_literal("[empty]"); }
    };
#endif // BOOST_LOG_USE_CHAR

#ifdef BOOST_LOG_USE_WCHAR_T
    template< >
    struct named_scope_test_data< wchar_t > :
        public test_data< wchar_t >,
        public named_scope_test_data_base
    {
        static logging::wstring_literal default_format() { return logging::str_literal(L"%n"); }
        static logging::wstring_literal full_format() { return logging::str_literal(L"%n (%f:%l)"); }
        static logging::wstring_literal short_filename_format() { return logging::str_literal(L"%n (%F:%l)"); }
        static logging::wstring_literal scope_function_name_format() { return logging::str_literal(L"%c"); }
        static logging::wstring_literal function_name_format() { return logging::str_literal(L"%C"); }
        static logging::wstring_literal delimiter1() { return logging::str_literal(L"|"); }
        static logging::wstring_literal incomplete_marker() { return logging::str_literal(L"<<and more>>"); }
        static logging::wstring_literal empty_marker() { return logging::str_literal(L"[empty]"); }
    };
#endif // BOOST_LOG_USE_WCHAR_T

    template< typename CharT >
    inline bool check_formatting(logging::basic_string_literal< CharT > const& format, logging::record_view const& rec, std::basic_string< CharT > const& expected)
    {
        typedef logging::basic_formatter< CharT > formatter;
        typedef std::basic_string< CharT > string;
        typedef logging::basic_formatting_ostream< CharT > osstream;
        typedef named_scope_test_data< CharT > data;

        string str;
        osstream strm(str);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(), keywords::format = format.c_str());
        f(rec, strm);
        return equal_strings(strm.str(), expected);
    }

} // namespace

// The test checks that named scopes stack formatting works
BOOST_AUTO_TEST_CASE_TEMPLATE(scopes_formatting, CharT, char_types)
{
    typedef attrs::named_scope named_scope;
    typedef named_scope::sentry sentry;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::basic_formatter< CharT > formatter;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    // First scope
    const unsigned int line1 = __LINE__;
    sentry scope1(data::scope1(), data::file(), line1);
    const unsigned int line2 = __LINE__;
    sentry scope2(data::scope2(), data::file(), line2);

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    // Default format
    {
        string str;
        osstream strm(str);
        strm << data::scope1() << "->" << data::scope2();
        BOOST_CHECK(check_formatting(data::default_format(), rec, strm.str()));
    }
    // Full format
    {
        string str;
        osstream strm(str);
        strm << data::scope1() << " (" << data::file() << ":" << line1 << ")->"
             << data::scope2() << " (" << data::file() << ":" << line2 << ")";
        BOOST_CHECK(check_formatting(data::full_format(), rec, strm.str()));
    }
    // Different delimiter
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::delimiter = data::delimiter1().c_str());
        f(rec, strm1);
        strm2 << data::scope1() << "|" << data::scope2();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    // Different direction
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::iteration = expr::reverse);
        f(rec, strm1);
        strm2 << data::scope2() << "<-" << data::scope1();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::delimiter = data::delimiter1().c_str(),
            keywords::iteration = expr::reverse);
        f(rec, strm1);
        strm2 << data::scope2() << "|" << data::scope1();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    // Limiting the number of scopes
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::depth = 1);
        f(rec, strm1);
        strm2 << "..." << data::scope2();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::depth = 1,
            keywords::iteration = expr::reverse);
        f(rec, strm1);
        strm2 << data::scope2() << "...";
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::delimiter = data::delimiter1().c_str(),
            keywords::depth = 1);
        f(rec, strm1);
        strm2 << "..." << data::scope2();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::delimiter = data::delimiter1().c_str(),
            keywords::depth = 1,
            keywords::iteration = expr::reverse);
        f(rec, strm1);
        strm2 << data::scope2() << "...";
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::incomplete_marker = data::incomplete_marker().c_str(),
            keywords::depth = 1);
        f(rec, strm1);
        strm2 << "<<and more>>" << data::scope2();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        formatter f = expr::stream << expr::format_named_scope(data::attr1(),
            keywords::format = data::default_format().c_str(),
            keywords::incomplete_marker = data::incomplete_marker().c_str(),
            keywords::depth = 1,
            keywords::iteration = expr::reverse);
        f(rec, strm1);
        strm2 << data::scope2() << "<<and more>>";
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
}

// The test checks that empty named scopes stack formatting works
BOOST_AUTO_TEST_CASE_TEMPLATE(empty_scopes_formatting, CharT, char_types)
{
    typedef attrs::named_scope named_scope;
    typedef named_scope::sentry sentry;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::basic_formatter< CharT > formatter;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    formatter f = expr::stream << expr::format_named_scope(data::attr1(),
        keywords::format = data::default_format().c_str(),
        keywords::empty_marker = data::empty_marker().c_str());

    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        f(rec, strm1);
        strm2 << "[empty]";
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }

    const unsigned int line1 = __LINE__;
    sentry scope1(data::scope1(), data::file(), line1);
    const unsigned int line2 = __LINE__;
    sentry scope2(data::scope2(), data::file(), line2);

    {
        string str1, str2;
        osstream strm1(str1), strm2(str2);
        f(rec, strm1);
        strm2 << data::scope1() << "->" << data::scope2();
        BOOST_CHECK(equal_strings(strm1.str(), strm2.str()));
    }
}

BOOST_AUTO_TEST_CASE_TEMPLATE(scopes_filename_formatting_posix, CharT, char_types)
{
    typedef attrs::named_scope named_scope;
    typedef named_scope::sentry sentry;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    // First scope
    const unsigned int line1 = __LINE__;
    sentry scope1(data::scope1(), data::posix_file(), line1);

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    // File names without the full path
    {
        string str;
        osstream strm(str);
        strm << data::scope1() << " (posix_file.cpp:" << line1 << ")";
        BOOST_CHECK(check_formatting(data::short_filename_format(), rec, strm.str()));
    }
}

#if defined(BOOST_WINDOWS)

BOOST_AUTO_TEST_CASE_TEMPLATE(scopes_filename_formatting_windows, CharT, char_types)
{
    typedef attrs::named_scope named_scope;
    typedef named_scope::sentry sentry;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    // First scope
    const unsigned int line1 = __LINE__;
    sentry scope1(data::scope1(), data::windows_file1(), line1);
    const unsigned int line2 = __LINE__;
    sentry scope2(data::scope2(), data::windows_file2(), line2);

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    // File names without the full path
    {
        string str;
        osstream strm(str);
        strm << data::scope1() << " (windows_file1.cpp:" << line1 << ")->"
             << data::scope2() << " (windows_file2.cpp:" << line2 << ")";
        BOOST_CHECK(check_formatting(data::short_filename_format(), rec, strm.str()));
    }
}

#endif // defined(BOOST_WINDOWS)

namespace {

struct named_scope_test_case
{
    logging::string_literal scope_name;
    const char* function_name;
    const char* function_name_no_scope;
};

const named_scope_test_case named_scope_test_cases[] =
{
    // Generic signatures
    { logging::str_literal("int main(int, char *[])"), "main", "main" },
    { logging::str_literal("namespace_name::type foo()"), "foo", "foo" },
    { logging::str_literal("namespace_name::type& foo::bar(int[], std::string const&)"), "foo::bar", "bar" },
    { logging::str_literal("void* namespc::foo<char>::bar()"), "namespc::foo<char>::bar", "bar" },
    { logging::str_literal("void* namespc::foo<char>::bar<int>(int) const"), "namespc::foo<char>::bar<int>", "bar<int>" },

    // MSVC-specific
    { logging::str_literal("int __cdecl main(int, char *[])"), "main", "main" },
    { logging::str_literal("struct namespc::strooct __cdecl foo3(int [])"), "foo3", "foo3" },
    { logging::str_literal("void (__cdecl *__cdecl foo4(void))(void)"), "foo4", "foo4" }, // function returning pointer to function
    { logging::str_literal("void (__cdecl *__cdecl foo5(void (__cdecl *)(void)))(void)"), "foo5", "foo5" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<int>::member1(void (__cdecl *)(void)))(void)"), "namespc::my_class<int>::member1", "member1" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<int>::member2<int>(int))(void)"), "namespc::my_class<int>::member2<int>", "member2<int>" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<int>::member2<void(__cdecl *)(void)>(void (__cdecl *)(void)))(void)"), "namespc::my_class<int>::member2<void(__cdecl *)(void)>", "member2<void(__cdecl *)(void)>" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<int>::member3<void __cdecl foo1(void)>(void))(void)"), "namespc::my_class<int>::member3<void __cdecl foo1(void)>", "member3<void __cdecl foo1(void)>" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<void (__cdecl*)(void)>::member1(void (__cdecl *)(void)))(void)"), "namespc::my_class<void (__cdecl*)(void)>::member1", "member1" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<void (__cdecl*)(void)>::member2<int>(int))(void)"), "namespc::my_class<void (__cdecl*)(void)>::member2<int>", "member2<int>" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<void (__cdecl*)(void)>::member2<void(__cdecl *)(void)>(void (__cdecl *)(void)))(void)"), "namespc::my_class<void (__cdecl*)(void)>::member2<void(__cdecl *)(void)>", "member2<void(__cdecl *)(void)>" },
    { logging::str_literal("void (__cdecl *__cdecl namespc::my_class<void (__cdecl*)(void)>::member3<void __cdecl foo1(void)>(void))(void)"), "namespc::my_class<void (__cdecl*)(void)>::member3<void __cdecl foo1(void)>", "member3<void __cdecl foo1(void)>" },
    { logging::str_literal("void (__cdecl namespc::my_class2::* __cdecl namespc::foo6(void (__cdecl *)(void)))(void)"), "namespc::foo6", "foo6" },
    { logging::str_literal("struct namespc::my_class<void __cdecl(int)> __cdecl namespc::foo7(void)"), "namespc::foo7", "foo7" },
    { logging::str_literal("void (__cdecl namespc::my_class2::* const (&__cdecl namespc::foo8(void (__cdecl *)(void)))[2])(void)"), "namespc::foo8", "foo8" },
    { logging::str_literal("__cdecl namespc::my_class2::my_class2(void)"), "namespc::my_class2::my_class2", "my_class2" },
    { logging::str_literal("__cdecl namespc::my_class2::~my_class2(void)"), "namespc::my_class2::~my_class2", "~my_class2" },
    { logging::str_literal("void __cdecl namespc::my_class2::operator =(const struct namespc::my_class2 &)"), "namespc::my_class2::operator =", "operator =" },
    { logging::str_literal("void __cdecl namespc::my_class2::operator *(void) const"), "namespc::my_class2::operator *", "operator *" },
    { logging::str_literal("void __cdecl namespc::my_class2::operator ()(void)"), "namespc::my_class2::operator ()", "operator ()" },
    { logging::str_literal("bool __cdecl namespc::my_class2::operator <(int) const"), "namespc::my_class2::operator <", "operator <" },
    { logging::str_literal("bool __cdecl namespc::my_class2::operator >(int) const"), "namespc::my_class2::operator >", "operator >" },
    { logging::str_literal("bool __cdecl namespc::my_class2::operator <=(int) const"), "namespc::my_class2::operator <=", "operator <=" },
    { logging::str_literal("bool __cdecl namespc::my_class2::operator >=(int) const"), "namespc::my_class2::operator >=", "operator >=" },
    { logging::str_literal("__cdecl namespc::my_class2::operator bool(void) const"), "namespc::my_class2::operator bool", "operator bool" },
    // MSVC generates incorrect strings in case of conversion operators to function types. We don't support these.
//    { logging::str_literal("__cdecl namespc::my_class2::operator char (__cdecl *)(double)(__cdecl *(void) const)(double)"), "namespc::my_class2::operator char (__cdecl *)(double)", "operator char (__cdecl *)(double)" },
//    { logging::str_literal("__cdecl namespc::my_class2::operator char (__cdecl namespc::my_class2::* )(double)(__cdecl namespc::my_class2::* (void) const)(double)"), "namespc::my_class2::operator char (__cdecl namespc::my_class2::* )(double)", "operator char (__cdecl namespc::my_class2::* )(double)" },
    { logging::str_literal("class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl namespc::operator <<<char,struct std::char_traits<char>>(class std::basic_ostream<char,struct std::char_traits<char> > &,const struct namespc::my_class2 &)"), "namespc::operator <<<char,struct std::char_traits<char>>", "operator <<<char,struct std::char_traits<char>>" },
    { logging::str_literal("class std::basic_istream<char,struct std::char_traits<char> > &__cdecl namespc::operator >><char,struct std::char_traits<char>>(class std::basic_istream<char,struct std::char_traits<char> > &,struct namespc::my_class2 &)"), "namespc::operator >><char,struct std::char_traits<char>>", "operator >><char,struct std::char_traits<char>>" },

    // GCC-specific
    { logging::str_literal("namespc::strooct foo3(int*)"), "foo3", "foo3" },
    { logging::str_literal("void (* foo4())()"), "foo4", "foo4" }, // function returning pointer to function
    { logging::str_literal("void (* foo5(pfun2_t))()"), "foo5", "foo5" },
    { logging::str_literal("static void (* namespc::my_class<T>::member1(pfun2_t))() [with T = int; pfun1_t = void (*)(); pfun2_t = void (*)()]"), "namespc::my_class<T>::member1", "member1" },
    { logging::str_literal("static void (* namespc::my_class<T>::member2(U))() [with U = int; T = int; pfun2_t = void (*)()]"), "namespc::my_class<T>::member2", "member2" },
    { logging::str_literal("static void (* namespc::my_class<T>::member2(U))() [with U = void (*)(); T = int; pfun2_t = void (*)()]"), "namespc::my_class<T>::member2", "member2" },
    { logging::str_literal("static void (* namespc::my_class<T>::member3())() [with void (* Fun)() = foo1; T = int; pfun2_t = void (*)()]"), "namespc::my_class<T>::member3", "member3" },
    { logging::str_literal("static void (* namespc::my_class<T>::member1(pfun2_t))() [with T = void (*)(); pfun1_t = void (*)(); pfun2_t = void (*)()]"), "namespc::my_class<T>::member1", "member1" },
    { logging::str_literal("static void (* namespc::my_class<T>::member2(U))() [with U = int; T = void (*)(); pfun2_t = void (*)()]"), "namespc::my_class<T>::member2", "member2" },
    { logging::str_literal("static void (* namespc::my_class<T>::member2(U))() [with U = void (*)(); T = void (*)(); pfun2_t = void (*)()]"), "namespc::my_class<T>::member2", "member2" },
    { logging::str_literal("static void (* namespc::my_class<T>::member3())() [with void (* Fun)() = foo1; T = void (*)(); pfun2_t = void (*)()]"), "namespc::my_class<T>::member3", "member3" },
    { logging::str_literal("void (namespc::my_class2::* namespc::foo6(pfun2_t))()"), "namespc::foo6", "foo6" },
    { logging::str_literal("namespc::my_class<void(int)> namespc::foo7()"), "namespc::foo7", "foo7" },
    { logging::str_literal("void (namespc::my_class2::* const (& namespc::foo8(pfun2_t))[2])()"), "namespc::foo8", "foo8" },
    { logging::str_literal("namespc::my_class2::my_class2()"), "namespc::my_class2::my_class2", "my_class2" }, // constructor
    { logging::str_literal("namespc::my_class2::~my_class2()"), "namespc::my_class2::~my_class2", "~my_class2" }, // destructor
    { logging::str_literal("void namespc::my_class2::operator=(const namespc::my_class2&)"), "namespc::my_class2::operator=", "operator=" },
    { logging::str_literal("void namespc::my_class2::operator*() const"), "namespc::my_class2::operator*", "operator*" },
    { logging::str_literal("void namespc::my_class2::operator()()"), "namespc::my_class2::operator()", "operator()" },
    { logging::str_literal("bool namespc::my_class2::operator<(int) const"), "namespc::my_class2::operator<", "operator<" },
    { logging::str_literal("bool namespc::my_class2::operator>(int) const"), "namespc::my_class2::operator>", "operator>" },
    { logging::str_literal("bool namespc::my_class2::operator<=(int) const"), "namespc::my_class2::operator<=", "operator<=" },
    { logging::str_literal("bool namespc::my_class2::operator>=(int) const"), "namespc::my_class2::operator>=", "operator>=" },
    { logging::str_literal("namespc::my_class2::operator bool() const"), "namespc::my_class2::operator bool", "operator bool" },
    { logging::str_literal("namespc::my_class2::operator pfun1_t() const"), "namespc::my_class2::operator pfun1_t", "operator pfun1_t" },
    { logging::str_literal("std::basic_ostream<_CharT, _Traits>& namespc::operator<<(std::basic_ostream<_CharT, _Traits>&, const namespc::my_class2&) [with CharT = char; TraitsT = std::char_traits<char>]"), "namespc::operator<<", "operator<<" },
    { logging::str_literal("std::basic_istream<_CharT, _Traits>& namespc::operator>>(std::basic_istream<_CharT, _Traits>&, namespc::my_class2&) [with CharT = char; TraitsT = std::char_traits<char>]"), "namespc::operator>>", "operator>>" },

    // BOOST_CURRENT_FUNCTION fallback value
    { logging::str_literal("(unknown)"), "(unknown)", "(unknown)" }
};

} // namespace

// Function name formatting
BOOST_AUTO_TEST_CASE_TEMPLATE(scopes_scope_function_name_formatting, CharT, char_types)
{
    typedef attrs::named_scope named_scope;
    typedef named_scope::sentry sentry;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    // First scope
    const unsigned int line1 = __LINE__;

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    for (unsigned int i = 0; i < sizeof(named_scope_test_cases) / sizeof(*named_scope_test_cases); ++i)
    {
        sentry scope1(named_scope_test_cases[i].scope_name, data::file(), line1, attrs::named_scope_entry::function);
        string str;
        osstream strm(str);
        strm << named_scope_test_cases[i].function_name;
        BOOST_CHECK_MESSAGE(check_formatting(data::scope_function_name_format(), rec, strm.str()), "Scope name: " << named_scope_test_cases[i].scope_name);
    }
}

// Function name without scope formatting
BOOST_AUTO_TEST_CASE_TEMPLATE(scopes_function_name_formatting, CharT, char_types)
{
    typedef attrs::named_scope named_scope;
    typedef named_scope::sentry sentry;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    // First scope
    const unsigned int line1 = __LINE__;

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    for (unsigned int i = 0; i < sizeof(named_scope_test_cases) / sizeof(*named_scope_test_cases); ++i)
    {
        sentry scope1(named_scope_test_cases[i].scope_name, data::file(), line1, attrs::named_scope_entry::function);
        string str;
        osstream strm(str);
        strm << named_scope_test_cases[i].function_name_no_scope;
        BOOST_CHECK_MESSAGE(check_formatting(data::function_name_format(), rec, strm.str()), "Scope name: " << named_scope_test_cases[i].scope_name);
    }
}

// The test checks that function name formatters do not affect scopes denoted with BOOST_LOG_NAMED_SCOPE
BOOST_AUTO_TEST_CASE_TEMPLATE(function_name_does_not_affect_non_function_scopes, CharT, char_types)
{
    typedef attrs::named_scope named_scope;

    typedef logging::attribute_set attr_set;
    typedef std::basic_string< CharT > string;
    typedef logging::basic_formatting_ostream< CharT > osstream;
    typedef logging::record_view record_view;
    typedef named_scope_test_data< CharT > data;

    named_scope attr;

    attr_set set1;
    set1[data::attr1()] = attr;

    record_view rec = make_record_view(set1);

    {
        BOOST_LOG_NAMED_SCOPE("void foo()");
        string str;
        osstream strm(str);
        strm << "void foo()";
        BOOST_CHECK(check_formatting(data::scope_function_name_format(), rec, strm.str()));
        BOOST_CHECK(check_formatting(data::function_name_format(), rec, strm.str()));
    }
}


text:
/**
 * $Id$
 *
 * Copyright (C)
 * 2015 - $Date$
 *     Martin Wolf <ndhist@martin-wolf.org>
 *
 * This file is distributed under the BSD 2-Clause Open Source License
 * (See LICENSE file).
 *
 */
#include <boost/python.hpp>

#include <ndhist/stats/excess.hpp>

namespace bp = boost::python;

namespace ndhist {
namespace stats {

void register_excess()
{
    bp::def("excess"
      , &py::excess
      , ( bp::arg("hist")
        , bp::arg("axis")=bp::object()
        )
      , "Calculates the excess kurtosis along the given axis of the given    \n"
        "ndhist object. As in statistics, the excess kurtosis is defined as  \n"
        ":math:`Excess[x] = Kurtosis[x] - 3`.                                \n"
        "It is a measure how normaly distributed the distribution is.        \n"
        "This function generates a projection along the given axis and then  \n"
        "calculates the excess kurtosis.                                     \n"
        "If ``None`` is given as axis argument (the default), the excess     \n"
        "kurtosis for all individual axes of the ndhist object is calculated \n"
        "and returned as a tuple. But if the dimensionality of the histogram \n"
        "is 1, a scalar value is returned.                                   \n"
        "                                                                    \n"
        ".. note:: This function is only defined for ndhist objects with POD \n"
        "          type axis values AND POD type weight values.              \n"
    );
}

}// namespace stats
}// namespace ndhist

max_stars_repo_name: martwo/ndhist

max_issues_repo_name: martwo/ndhist

max_forks_repo_name: martwo/ndhist


text:
#define BOOST_TEST_MODULE pichi socks5 test

#include "utils.hpp"
#include <array>
#include <boost/test/unit_test.hpp>
#include <initializer_list>
#include <memory>
#include <pichi/common.hpp>
#include <pichi/config.hpp>
#include <pichi/net/asio.hpp>
#include <pichi/net/helpers.hpp>
#include <pichi/net/socks5.hpp>
#include <pichi/test/socket.hpp>
#include <vector>

using namespace std;
using namespace pichi;
namespace asio = boost::asio;
namespace sys = boost::system;

using test::Socket;
using Ingress = pichi::net::Socks5Ingress<test::Stream>;
using Egress = pichi::net::Socks5Egress<test::Stream>;
using Credentials = unordered_map<string, string>;
using Credential = optional<pair<string, string>>;

static auto const CREDENTIALS = Credentials{{"pichi"s, "pichi"s}};
static auto const CREDENTIAL = make_pair("pichi"s, "pichi"s);
static asio::detail::Pull* pPull = nullptr;
static asio::detail::Push* pPush = nullptr;
static asio::yield_context yield = {*pPush, *pPull};

static void fillString(Socket& s, string_view str)
{
  s.fill({static_cast<uint8_t>(str.size())});
  s.fill(ConstBuffer<uint8_t>{str});
}

static void verifyString(Socket& s, string_view str)
{
  BOOST_CHECK_GE(s.available(), str.size() + 1);
  auto holder = array<uint8_t, 0x100>{};
  auto data = MutableBuffer<uint8_t>{holder, str.size() + 1};
  s.flush(data);
  BOOST_CHECK_EQUAL(static_cast<uint8_t>(str.size()), *data.data());
  BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(str), cend(str), cbegin(data) + 1, cend(data));
}

BOOST_AUTO_TEST_SUITE(SOCKS5)

BOOST_AUTO_TEST_CASE(readRemote_Handshake_Invalid_Version)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 0x05) continue;
    auto ver = static_cast<uint8_t>(i);
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

    socket.fill({ver, 0x01, 0x00});
    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);
    BOOST_CHECK_EQUAL(0_sz, socket.available());
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Handshake_Zero_Nmethod)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

  socket.fill({0x05, 0x00});
  BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                        verifyException<PichiError::BAD_PROTO>);
  BOOST_CHECK_EQUAL(0_sz, socket.available());
}

BOOST_AUTO_TEST_CASE(readRemote_Handshake_Without_Acceptable_Method)
{
  for (auto i = 1; i < 0x100; ++i) {
    auto len = static_cast<uint8_t>(i);
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

    socket.fill({0x05, len});
    for (auto j = 0; j < len; ++j) socket.fill({len});
    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_AUTH_METHOD>);
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Handshake_Without_Acceptable_Method_Credentials)
{
  for (auto i = 1; i < 0x100; ++i) {
    auto len = static_cast<uint8_t>(1);
    auto method = static_cast<uint8_t>(len <= 2 ? len - 1 : len);
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

    socket.fill({0x05, len});
    for (auto j = 0; j < len; ++j) socket.fill({method});
    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_AUTH_METHOD>);
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Handshake_With_Acceptable_Method)
{
  for (auto i = 1; i < 0x100; ++i) {
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

    socket.fill({0x05, 0xff});
    for (auto j = 0; j < 0x100; ++j)
      if (j == i - 1)
        socket.fill({0x00});
      else
        socket.fill({0xff});
    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception, verifyException<PichiError::MISC>);

    auto fact = array<uint8_t, 2>{};
    BOOST_CHECK_EQUAL(2_sz, socket.available());
    socket.flush(fact);
    BOOST_CHECK_EQUAL(0x05, fact.front());
    BOOST_CHECK_EQUAL(0x00, fact.back());
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Authenticate_With_Invalid_Version)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 1) continue; // Valid VER
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

    socket.fill({
        0x05, 0x01, 0x02,       // Handshake
        static_cast<uint8_t>(i) // Invalid VER
    });
    fillString(socket, cbegin(CREDENTIALS)->first);
    fillString(socket, cbegin(CREDENTIALS)->second);

    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    BOOST_CHECK_EQUAL(2_sz, socket.available());
    auto received = array<uint8_t, 2>{};
    socket.flush(received);
    BOOST_CHECK_EQUAL(0x05, received.front());
    BOOST_CHECK_EQUAL(0x02, received.back());
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Authenticate_With_Empty_Username)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

  socket.fill({
      0x05, 0x01, 0x02, // Handshake
      0x01,             // VER
      0x00              // Empty username
  });
  fillString(socket, cbegin(CREDENTIALS)->second);

  BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                        verifyException<PichiError::BAD_PROTO>);

  BOOST_CHECK_EQUAL(2_sz, socket.available());
  auto received = array<uint8_t, 2>{};
  socket.flush(received);
  BOOST_CHECK_EQUAL(0x05, received.front());
  BOOST_CHECK_EQUAL(0x02, received.back());
}

BOOST_AUTO_TEST_CASE(readRemote_Authenticate_With_Empty_Password)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

  socket.fill({0x05, 0x01, 0x02, 0x01});
  fillString(socket, cbegin(CREDENTIALS)->first);
  socket.fill({0x00}); // Empty password

  BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                        verifyException<PichiError::BAD_PROTO>);

  BOOST_CHECK_EQUAL(2_sz, socket.available());
  auto received = array<uint8_t, 2>{};
  socket.flush(received);
  BOOST_CHECK_EQUAL(0x05, received.front());
  BOOST_CHECK_EQUAL(0x02, received.back());
}

BOOST_AUTO_TEST_CASE(readRemote_Authenticate_With_Nonexisting_User)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

  socket.fill({
      0x05, 0x01, 0x02, // Handshake
      0x01,             // VER
      0x01, 0x50        // Username
  });
  fillString(socket, cbegin(CREDENTIALS)->second);

  BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                        verifyException<PichiError::UNAUTHENTICATED>);

  BOOST_CHECK_EQUAL(2_sz, socket.available());
  auto received = array<uint8_t, 2>{};
  socket.flush(received);
  BOOST_CHECK_EQUAL(0x05, received.front());
  BOOST_CHECK_EQUAL(0x02, received.back());
}

BOOST_AUTO_TEST_CASE(readRemote_Authenticate_With_Incorrect_Password)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

  socket.fill({0x05, 0x01, 0x02, 0x01});
  fillString(socket, cbegin(CREDENTIALS)->first);
  socket.fill({0x01, 0x50});

  BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                        verifyException<PichiError::UNAUTHENTICATED>);

  BOOST_CHECK_EQUAL(2_sz, socket.available());
  auto received = array<uint8_t, 2>{};
  socket.flush(received);
  BOOST_CHECK_EQUAL(0x05, received.front());
  BOOST_CHECK_EQUAL(0x02, received.back());
}

BOOST_AUTO_TEST_CASE(readRemote_Request_With_Invalid_Version)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 0x05) continue;
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

    socket.fill({
        0x05, 0x01, 0x00,                        // Handshake
        static_cast<uint8_t>(i),                 // VER
        0x01,                                    // CMD
        0x00,                                    // RSV
        0x01, 0x7f, 0x00, 0x00, 0x01, 0x01, 0xbb // Endpoint
    });

    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    auto fact = array<uint8_t, 2>{};
    BOOST_CHECK_EQUAL(2_sz, socket.available());
    socket.flush(fact);
    BOOST_CHECK_EQUAL(0x05, fact.front());
    BOOST_CHECK_EQUAL(0x00, fact.back());
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Request_With_Invalid_CMD)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 0x01) continue;
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

    socket.fill({
        0x05, 0x01, 0x00,                        // Handshake
        0x05,                                    // VER
        static_cast<uint8_t>(i),                 // CMD
        0x00,                                    // RSV
        0x01, 0x7f, 0x00, 0x00, 0x01, 0x01, 0xbb // Endpoint
    });

    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    auto fact = array<uint8_t, 2>{};
    BOOST_CHECK_EQUAL(2_sz, socket.available());
    socket.flush(fact);
    BOOST_CHECK_EQUAL(0x05, fact.front());
    BOOST_CHECK_EQUAL(0x00, fact.back());
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Request_With_Invalid_RSV)
{
  for (auto i = 1; i < 0x100; ++i) {
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

    socket.fill({
        0x05, 0x01, 0x00,                        // Handshake
        0x05,                                    // VER
        0x01,                                    // CMD
        static_cast<uint8_t>(i),                 // RSV
        0x01, 0x7f, 0x00, 0x00, 0x01, 0x01, 0xbb // Endpoint
    });

    BOOST_CHECK_EXCEPTION(ingress->readRemote(yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    auto fact = array<uint8_t, 2>{};
    BOOST_CHECK_EQUAL(2_sz, socket.available());
    socket.flush(fact);
    BOOST_CHECK_EQUAL(0x05, fact.front());
    BOOST_CHECK_EQUAL(0x00, fact.back());
  }
}

BOOST_AUTO_TEST_CASE(readRemote_Without_Authentication)
{
  auto expect = net::makeEndpoint("::1"sv, "443"sv);
  auto otects = array<uint8_t, 19>{};

  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

  socket.fill({0x05, 0x01, 0x00, 0x05, 0x01, 0x00});

  net::serializeEndpoint(expect, otects);
  socket.fill(otects);

  auto fact = ingress->readRemote(yield);

  BOOST_CHECK_EQUAL(2_sz, socket.available());
  socket.flush({otects, 2});
  BOOST_CHECK_EQUAL(0x05, otects[0]);
  BOOST_CHECK_EQUAL(0x00, otects[1]);

  BOOST_CHECK(expect.type_ == fact.type_);
  BOOST_CHECK_EQUAL(expect.host_, fact.host_);
  BOOST_CHECK_EQUAL(expect.port_, fact.port_);
}

BOOST_AUTO_TEST_CASE(readRemote_With_Correct_Credential)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(CREDENTIALS, socket, true);

  socket.fill({0x05, 0x01, 0x02, 0x01});
  fillString(socket, cbegin(CREDENTIALS)->first);
  fillString(socket, cbegin(CREDENTIALS)->second);
  socket.fill({0x05, 0x01, 0x00});

  auto expect = net::makeEndpoint("::1"sv, "443"sv);
  auto otects = array<uint8_t, 19>{};

  net::serializeEndpoint(expect, otects);
  socket.fill(otects);

  auto fact = ingress->readRemote(yield);

  BOOST_CHECK_EQUAL(4_sz, socket.available());
  socket.flush({otects, 4});
  BOOST_CHECK_EQUAL(0x05, otects[0]);
  BOOST_CHECK_EQUAL(0x02, otects[1]);
  BOOST_CHECK_EQUAL(0x01, otects[2]);
  BOOST_CHECK_EQUAL(0x00, otects[3]);

  BOOST_CHECK(expect.type_ == fact.type_);
  BOOST_CHECK_EQUAL(expect.host_, fact.host_);
  BOOST_CHECK_EQUAL(expect.port_, fact.port_);
}

BOOST_AUTO_TEST_CASE(readRemote_With_Multiple_Credentials)
{
  auto credentials = CREDENTIALS;
  credentials[ph] = ph;

  for (auto&& item : credentials) {
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(credentials, socket, true);

    socket.fill({0x05, 0x01, 0x02, 0x01});
    fillString(socket, item.first);
    fillString(socket, item.second);
    socket.fill({0x05, 0x01, 0x00});

    auto expect = net::makeEndpoint("::1"sv, "443"sv);
    auto otects = array<uint8_t, 19>{};
    net::serializeEndpoint(expect, otects);
    socket.fill(otects);

    auto fact = ingress->readRemote(yield);

    BOOST_CHECK_EQUAL(4_sz, socket.available());
    socket.flush({otects, 4});
    BOOST_CHECK_EQUAL(0x05, otects[0]);
    BOOST_CHECK_EQUAL(0x02, otects[1]);
    BOOST_CHECK_EQUAL(0x01, otects[2]);
    BOOST_CHECK_EQUAL(0x00, otects[3]);

    BOOST_CHECK(expect.type_ == fact.type_);
    BOOST_CHECK_EQUAL(expect.host_, fact.host_);
    BOOST_CHECK_EQUAL(expect.port_, fact.port_);
  }
}

BOOST_AUTO_TEST_CASE(connect_Handshake_Invalid_Version)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 0x05) continue;
    auto socket = Socket{};
    auto egress = make_unique<Egress>(Credential{}, socket);

    socket.fill({static_cast<uint8_t>(i), 0x00});
    BOOST_CHECK_EXCEPTION(egress->connect({}, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    BOOST_CHECK_EQUAL(3_sz, socket.available());
    auto req = array<uint8_t, 3>{};
    socket.flush(req);
    BOOST_CHECK_EQUAL(0x05, req[0]);
    BOOST_CHECK_EQUAL(0x01, req[1]);
    BOOST_CHECK_EQUAL(0x00, req[2]);
  }
}

BOOST_AUTO_TEST_CASE(connect_Handshake_Without_Acceptable_Method)
{
  for (auto i = 1; i < 0x100; ++i) {
    auto socket = Socket{};
    auto egress = make_unique<Egress>(Credential{}, socket);

    socket.fill({0x05, static_cast<uint8_t>(i)});
    BOOST_CHECK_EXCEPTION(egress->connect({}, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    BOOST_CHECK_EQUAL(3_sz, socket.available());
    auto req = array<uint8_t, 3>{};
    socket.flush(req);
    BOOST_CHECK_EQUAL(0x05, req[0]);
    BOOST_CHECK_EQUAL(0x01, req[1]);
    BOOST_CHECK_EQUAL(0x00, req[2]);
  }
}

BOOST_AUTO_TEST_CASE(connect_Handshake_Without_Acceptable_Method_Credential)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 2) continue;
    auto socket = Socket{};
    auto egress = make_unique<Egress>(CREDENTIAL, socket);

    socket.fill({0x05, static_cast<uint8_t>(i)});
    BOOST_CHECK_EXCEPTION(egress->connect({}, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    BOOST_CHECK_EQUAL(3_sz, socket.available());
    auto req = array<uint8_t, 3>{};
    socket.flush(req);
    BOOST_CHECK_EQUAL(0x05, req[0]);
    BOOST_CHECK_EQUAL(0x01, req[1]);
    BOOST_CHECK_EQUAL(0x02, req[2]);
  }
}

BOOST_AUTO_TEST_CASE(connect_Authentication_With_Invalid_Version)
{
  for (auto i = 0; i < 0x100; ++i) {
    if (i == 1) continue;
    auto socket = Socket{};
    auto egress = make_unique<Egress>(CREDENTIAL, socket);

    socket.fill({0x05, 0x02});
    socket.fill({static_cast<uint8_t>(i), 0x00});

    BOOST_CHECK_EXCEPTION(egress->connect({}, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);
    BOOST_CHECK_GE(socket.available(), 4_sz);
    auto received = array<uint8_t, 4>{};
    socket.flush(received);
    BOOST_CHECK_EQUAL(0x05, received[0]);
    BOOST_CHECK_EQUAL(0x01, received[1]);
    BOOST_CHECK_EQUAL(0x02, received[2]);
    BOOST_CHECK_EQUAL(0x01, received[3]);
    verifyString(socket, CREDENTIAL.first);
    verifyString(socket, CREDENTIAL.first);
    BOOST_CHECK_EQUAL(0_sz, socket.available());
  }
}

BOOST_AUTO_TEST_CASE(connect_Authentication_Failed)
{
  for (auto i = 1; i < 0x100; ++i) {
    auto socket = Socket{};
    auto egress = make_unique<Egress>(CREDENTIAL, socket);

    socket.fill({0x05, 0x02});
    socket.fill({0x01, static_cast<uint8_t>(i)});

    BOOST_CHECK_EXCEPTION(egress->connect({}, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);
    BOOST_CHECK_GE(socket.available(), 4_sz);
    auto received = array<uint8_t, 4>{};
    socket.flush(received);
    BOOST_CHECK_EQUAL(0x05, received[0]);
    BOOST_CHECK_EQUAL(0x01, received[1]);
    BOOST_CHECK_EQUAL(0x02, received[2]);
    BOOST_CHECK_EQUAL(0x01, received[3]);
    verifyString(socket, CREDENTIAL.first);
    verifyString(socket, CREDENTIAL.first);
    BOOST_CHECK_EQUAL(0_sz, socket.available());
  }
}

BOOST_AUTO_TEST_CASE(connect_Reply_With_Invalid_Version)
{
  auto expect = array<uint8_t, 25>{0x05, 0x01, 0x00, 0x05, 0x01, 0x00};
  auto remote = net::makeEndpoint("::1"sv, "443"sv);
  net::serializeEndpoint(remote, MutableBuffer<uint8_t>{expect} + 6);

  for (auto i = 0; i < 0x100; ++i) {
    if (i == 0x05) continue;
    auto socket = Socket{};
    auto egress = make_unique<Egress>(Credential{}, socket);

    socket.fill({0x05, 0x00});
    socket.fill({static_cast<uint8_t>(i), 0x00, 0x00});
    BOOST_CHECK_EXCEPTION(egress->connect(remote, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    BOOST_CHECK_EQUAL(25_sz, socket.available());
    auto fact = array<uint8_t, 25>{};
    socket.flush(fact);
    BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(expect), cend(expect), cbegin(fact), cend(fact));
  }
}

BOOST_AUTO_TEST_CASE(connect_Reply_Connection_Failure)
{
  auto expect = array<uint8_t, 25>{0x05, 0x01, 0x00, 0x05, 0x01, 0x00};
  auto remote = net::makeEndpoint("::1"sv, "443"sv);
  net::serializeEndpoint(remote, MutableBuffer<uint8_t>{expect} + 6);

  for (auto i = 1; i < 0x100; ++i) {
    auto socket = Socket{};
    auto egress = make_unique<Egress>(Credential{}, socket);

    socket.fill({0x05, 0x00});
    socket.fill({0x05, static_cast<uint8_t>(i), 0x00});
    BOOST_CHECK_EXCEPTION(egress->connect(remote, {}, yield), Exception,
                          verifyException<PichiError::CONN_FAILURE>);

    BOOST_CHECK_EQUAL(25_sz, socket.available());
    auto fact = array<uint8_t, 25>{};
    socket.flush(fact);
    BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(expect), cend(expect), cbegin(fact), cend(fact));
  }
}

BOOST_AUTO_TEST_CASE(connect_Reply_With_Invalid_RSV)
{
  auto expect = array<uint8_t, 25>{0x05, 0x01, 0x00, 0x05, 0x01, 0x00};
  auto remote = net::makeEndpoint("::1"sv, "443"sv);
  net::serializeEndpoint(remote, MutableBuffer<uint8_t>{expect} + 6);

  for (auto i = 1; i < 0x100; ++i) {
    auto socket = Socket{};
    auto egress = make_unique<Egress>(Credential{}, socket);

    socket.fill({0x05, 0x00});
    socket.fill({0x05, 0x00, static_cast<uint8_t>(i)});
    BOOST_CHECK_EXCEPTION(egress->connect(remote, {}, yield), Exception,
                          verifyException<PichiError::BAD_PROTO>);

    BOOST_CHECK_EQUAL(25_sz, socket.available());
    auto fact = array<uint8_t, 25>{};
    socket.flush(fact);
    BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(expect), cend(expect), cbegin(fact), cend(fact));
  }
}

BOOST_AUTO_TEST_CASE(connect_Reply_Invalid_Endpoint)
{
  auto expect = array<uint8_t, 25>{0x05, 0x01, 0x00, 0x05, 0x01, 0x00};
  auto remote = net::makeEndpoint("::1"sv, "443"sv);
  net::serializeEndpoint(remote, MutableBuffer<uint8_t>{expect} + 6);

  auto socket = Socket{};
  auto egress = make_unique<Egress>(Credential{}, socket);

  socket.fill({0x05, 0x00});
  socket.fill({0x05, 0x00, 0x00});
  socket.fill({0x00});
  BOOST_CHECK_EXCEPTION(egress->connect(remote, {}, yield), Exception,
                        verifyException<PichiError::BAD_PROTO>);

  BOOST_CHECK_EQUAL(25_sz, socket.available());
  auto fact = array<uint8_t, 25>{};
  socket.flush(fact);
  BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(expect), cend(expect), cbegin(fact), cend(fact));
}

BOOST_AUTO_TEST_CASE(connect_Reply_Correct)
{
  auto expect = array<uint8_t, 25>{0x05, 0x01, 0x00, 0x05, 0x01, 0x00};
  auto remote = net::makeEndpoint("::1"sv, "443"sv);
  net::serializeEndpoint(remote, MutableBuffer<uint8_t>{expect} + 6);

  auto socket = Socket{};
  auto egress = make_unique<Egress>(Credential{}, socket);

  socket.fill({0x05, 0x00});
  socket.fill({0x05, 0x00, 0x00});
  socket.fill({0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00});

  egress->connect(remote, {}, yield);

  BOOST_CHECK_EQUAL(25_sz, socket.available());
  auto fact = array<uint8_t, 25>{};
  socket.flush(fact);
  BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(expect), cend(expect), cbegin(fact), cend(fact));
}

BOOST_AUTO_TEST_CASE(confirm)
{
  auto socket = Socket{};
  auto ingress = make_unique<Ingress>(Credentials{}, socket, true);

  ingress->confirm(yield);

  auto buf = array<uint8_t, 512>{};
  socket.flush({buf, 3});
  BOOST_CHECK_EQUAL(0x05, buf[0]);
  BOOST_CHECK_EQUAL(0x00, buf[1]);
  BOOST_CHECK_EQUAL(0x00, buf[2]);

  auto consumed = 0_sz;
  auto len = socket.available();
  socket.flush({buf, len});
  net::parseEndpoint([src = ConstBuffer<uint8_t>{buf, len}, &consumed](auto dst) mutable {
    BOOST_CHECK_GE(src.size(), dst.size());
    copy_n(cbegin(src), dst.size(), begin(dst));
    src += dst.size();
    consumed += dst.size();
  });
  BOOST_CHECK_EQUAL(len, consumed);
}

BOOST_AUTO_TEST_CASE(disconnect_For_Named_Failures)
{
  auto const FAILURE_MAP = unordered_map<PichiError, vector<uint8_t>>{
      {PichiError::CONN_FAILURE,
       {0x05_u8, 0x04_u8, 0x00_u8, 0x01_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8, 0x00_u8}},
      {PichiError::BAD_AUTH_METHOD, {0x05_u8, 0xff_u8}},
      {PichiError::UNAUTHENTICATED, {0x01_u8, 0xff_u8}}};
  for (auto&& p : FAILURE_MAP) {
    auto&& [e, expect] = p;
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);
    ingress->disconnect(e, yield);

    auto fact = vector<uint8_t>(expect.size(), 0x00_u8);

    BOOST_CHECK_EQUAL(fact.size(), socket.available());

    socket.flush(fact);
    BOOST_CHECK_EQUAL_COLLECTIONS(cbegin(expect), cend(expect), cbegin(fact), cend(fact));
  }
}

BOOST_AUTO_TEST_CASE(disconnect_For_Unnamed_Failures)
{
  for (auto e : {PichiError::OK, PichiError::BAD_PROTO, PichiError::CRYPTO_ERROR,
                 PichiError::BUFFER_OVERFLOW, PichiError::BAD_JSON, PichiError::SEMANTIC_ERROR,
                 PichiError::RES_IN_USE, PichiError::RES_LOCKED, PichiError::MISC}) {
    auto socket = Socket{};
    auto ingress = make_unique<Ingress>(Credentials{}, socket, true);
    ingress->disconnect(e, yield);
    BOOST_CHECK_EQUAL(0_sz, socket.available());
  }
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: rosorio/pichi

max_issues_repo_name: rosorio/pichi

max_forks_repo_name: rosorio/pichi