<commit_before>#include "regex.h"

#include <iostream>
#include <algorithm>
#include <map>

#include "document.h"
#include "prolog.h"
#include "pi.h"
#include "doctype.h"
#include "attribute.h"
#include "element.h"
#include "composite_element.h"
#include "content.h"

static std::string schema_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string element_to_regex(Element *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string simple_element_to_regex(Element *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string complexe_type_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string choice_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string sequence_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types, bool mixed=false);

static const std::string re_string("[^<]*");
static const std::string re_date("[0-9]{4}-[0-9]{2}-[0-9]{2}(((\\+|-)[0-2][0-9]:[0-5][0-9])|Z)?");
static const std::string re_mixed("[^<]*");
static const std::string re_blank("\\s*");
static const std::string re_S("(\\s+)");
static const std::string re_Eq(re_S + "?=" + re_S + "?");
static const std::string re_Name("[:A-Za-z\\200-\\377_][:A-Za-z\\200-\\377_0-9.-]*");
static const std::string re_AttValue("(\"[^<&\"]*\"|\'[^<&\"]*\')");
static const std::string re_Attr(re_Name + re_Eq + re_AttValue);
static const std::string re_version_info(re_S + "version" + re_Eq + "(\"1\\.[0-9]+\"|'1\\.[0-9]+')");
static const std::string re_encoding_decl(re_S + "encoding" + re_Eq + re_AttValue);
static const std::string re_sd_decl(re_S + re_Attr);
static const std::string re_xml_decl("<\\?xml(" +
    re_version_info + ")?(" +
    re_encoding_decl + ")?(" +
    re_sd_decl + ")? ?\\?>");
static const std::string re_comment("<!--([^-]|-[^-])*-->");
static const std::string re_PI("<\\?" + re_Name + "(" + re_S + re_Attr + ")*\\?>");
static const std::string re_Misc("(" + re_comment + "|" + re_PI + "|" + re_S + ")");
static const std::string re_doctype_decl("<!DOCTYPE" + re_S + re_Name + "(" + re_S + re_Name + ")?(" + re_S + re_AttValue + ")?" + re_S + "?>");
static const std::string re_prolog("(" + re_xml_decl + ")?" + re_Misc + "*(" + re_doctype_decl + re_Misc + "*)?");

std::string xsd_to_regex(Document * doc)
{
  // std::cout << "xml : " << re_xml_decl << std::endl;
  // std::cout << "doc : " << re_doctype_decl << std::endl;
  // std::cout << "com : " << re_comment << std::endl;
  // std::cout << "pi  : " << re_PI << std::endl;
  // std::cout << "pro : " << re_prolog << std::endl;
  CompositeElement * root = dynamic_cast<CompositeElement *>(doc->root());
  if (root == nullptr)
    return "^$";

  auto it_ns = std::find_if(root->attributes().begin(), root->attributes().end(),
      [](Attribute * a) { return a->name().substr(0, 5) == "xmlns" && a->value().substr(a->value().length() - 9, 9) == "XMLSchema"; });
  if (it_ns == root->attributes().end())
    return "^$";

  std::string xs_ns = (*it_ns)->name().substr(6);
  if (root->begin_tag() == xs_ns + ":schema")
  {
    std::map<std::string, std::string> refs;
    std::map<std::string, std::string> types;
    std::string re("^" + re_prolog + schema_to_regex(root, xs_ns, refs, types) + re_Misc + "*$");
    std::cout << re << std::endl; // Mais oui c'est clair
    return re;
  }
  return "^$";
}

std::string schema_to_regex(CompositeElement * s,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  std::string r;
  for (auto c : s->content())
  {
    auto e = dynamic_cast<Element *>(c);
    if (e != nullptr && e->name() == xs_ns + ":element")
      r += element_to_regex(e, xs_ns, refs, types) + "|";

    auto ce = dynamic_cast<CompositeElement *>(c);
    if (ce != nullptr && ce->begin_tag() == xs_ns + ":complexType")
    {
      complexe_type_to_regex(ce, xs_ns, refs, types);
    }
  }
  r = r.substr(0, r.length() - 1);
  return "(" + r + ")";
}

std::string element_to_regex(Element * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  auto it_name = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "name"; });
  if (it_name == e->attributes().end())
  {
    auto it_ref = std::find_if(e->attributes().begin(), e->attributes().end(),
        [](Attribute * a) { return a->name() == "ref"; });
    if (it_ref == e->attributes().end())
      return "";

    auto ref = (*it_ref)->value();
    auto r = refs.find(ref);
    if (r == refs.end())
      return "";
    return r->second;
  }

  auto name = (*it_name)->value();
  const std::string begin("<" + name + "(" + re_S + re_Attr + ")*" + re_blank + ">");
  const std::string end("</" + name + re_blank + ">");

  auto ce = dynamic_cast<CompositeElement *>(e);
  if (ce != nullptr)
  {
    CompositeElement * cce = nullptr;
    if (ce->content().size() >= 1
        && (cce = dynamic_cast<CompositeElement *>(ce->content().front())) != nullptr
        && cce->begin_tag() == xs_ns + ":complexType")
    {
      std::string r(begin + complexe_type_to_regex(cce, xs_ns, refs, types) + end);
      refs[name] = r;
      return r;
    }
  }
  else
  {
    std::string r(begin + simple_element_to_regex(e, xs_ns, refs, types) + end);
    refs[name] = r;
    return r;
  }
  return "";
}

std::string simple_element_to_regex(Element * e,
    std::string xs_ns,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types)
{
  auto it_type = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "type"; });
  if (it_type == e->attributes().end())
    return "";

  auto type = (*it_type)->value();
  if (type == xs_ns + ":string")
    return re_string;
  else if (type == xs_ns + ":date")
    return re_date;

  auto it_ptype = types.find(type);
  if (it_ptype != types.end())
  {
    return "(" + it_ptype->second + ")";
  }

  return "";
}

std::string complexe_type_to_regex(CompositeElement * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  if (e->content().size() < 1)
    return "";

  CompositeElement * ce = dynamic_cast<CompositeElement *>(e->content().front());
  if (ce == nullptr)
    return "";

  bool mixed = false;
  auto it_mixed = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "mixed"; });
  if (it_mixed != e->attributes().end()
      && (*it_mixed)->value() == "true")
    mixed = true;

  std::string s;
  if (ce->begin_tag() == xs_ns + ":choice")
  {
    if (mixed)
      s += re_mixed;
    s += choice_to_regex(ce, xs_ns, refs, types);
    if (mixed)
      s += re_mixed;
  }
  else if (ce->begin_tag() == xs_ns + ":sequence")
  {
    s += sequence_to_regex(ce, xs_ns, refs, types, mixed);
  }

  auto it_name = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "name"; });
  if (it_name != e->attributes().end())
  {
    types[(*it_name)->value()] = s;
  }

  return s;
}

std::string choice_to_regex(CompositeElement * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  std::string s;
  for (auto c : e->content())
  {
    auto ce = dynamic_cast<Element *>(c);
    if (ce)
    {
      s += element_to_regex(ce, xs_ns, refs, types);
      if (c != e->content().back())
        s += "|";
    }
  }
  return re_blank + "(" + s + ")" + re_blank;
}

std::string sequence_to_regex(CompositeElement * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types, bool mixed)
{
  std::string s;
  std::string space = mixed ? re_mixed : re_blank;
  for (auto c : e->content())
  {
    auto ce = dynamic_cast<Element *>(c);
    if (ce)
    {
      auto it_maxOccurs = std::find_if(ce->attributes().begin(),
          ce->attributes().end(),
          [](Attribute * a) { return a->name() == "maxOccurs"; });
      std::string reg = element_to_regex(ce, xs_ns, refs, types) + space;
      if (it_maxOccurs != ce->attributes().end())
      {
        int maxOccurs = atoi((*it_maxOccurs)->value().c_str());
        for (int i(0); i < maxOccurs; i++) {
          s += reg;
        }
      }
      else
      {
        s += reg;
      }
    }
  }
  return space + s;
}

<commit_msg>33 tests<commit_after>#include "regex.h"

#include <iostream>
#include <algorithm>
#include <map>

#include "document.h"
#include "prolog.h"
#include "pi.h"
#include "doctype.h"
#include "attribute.h"
#include "element.h"
#include "composite_element.h"
#include "content.h"

static std::string schema_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string element_to_regex(Element *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string simple_element_to_regex(Element *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string complexe_type_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string choice_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types);
static std::string sequence_to_regex(CompositeElement *, std::string,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types, bool mixed=false);

static const std::string re_string("[^<]*");
static const std::string re_date("[0-9]{4}-[0-9]{2}-[0-9]{2}(((\\+|-)[0-2][0-9]:[0-5][0-9])|Z)?");
static const std::string re_mixed("[^<]*");
static const std::string re_blank("\\s*");
static const std::string re_S("(\\s+)");
static const std::string re_Eq(re_S + "?=" + re_S + "?");
static const std::string re_Name("[:A-Za-z\\200-\\377_][:A-Za-z\\200-\\377_0-9.-]*");
static const std::string re_AttValue("(\"[^<&\"]*\"|\'[^<&\"]*\')");
static const std::string re_Attr(re_Name + re_Eq + re_AttValue);
static const std::string re_version_info(re_S + "version" + re_Eq + "(\"1\\.[0-9]+\"|'1\\.[0-9]+')");
static const std::string re_encoding_decl(re_S + "encoding" + re_Eq + re_AttValue);
static const std::string re_sd_decl(re_S + re_Attr);
static const std::string re_xml_decl("<\\?xml(" +
    re_version_info + ")?(" +
    re_encoding_decl + ")?(" +
    re_sd_decl + ")? ?\\?>");
static const std::string re_comment("<!--([^-]|-[^-])*-->");
static const std::string re_PI("<\\?" + re_Name + "(" + re_S + re_Attr + ")*\\?>");
static const std::string re_Misc("(" + re_comment + "|" + re_PI + "|" + re_S + ")");
static const std::string re_doctype_decl("<!DOCTYPE" + re_S + re_Name + "(" + re_S + re_Name + ")?(" + re_S + re_AttValue + ")?" + re_S + "?>");
static const std::string re_prolog("(" + re_xml_decl + ")?" + re_Misc + "*(" + re_doctype_decl + re_Misc + "*)?");

std::string xsd_to_regex(Document * doc)
{
  // std::cout << "xml : " << re_xml_decl << std::endl;
  // std::cout << "doc : " << re_doctype_decl << std::endl;
  // std::cout << "com : " << re_comment << std::endl;
  // std::cout << "pi  : " << re_PI << std::endl;
  // std::cout << "pro : " << re_prolog << std::endl;
  CompositeElement * root = dynamic_cast<CompositeElement *>(doc->root());
  if (root == nullptr)
    return "^$";

  auto it_ns = std::find_if(root->attributes().begin(), root->attributes().end(),
      [](Attribute * a) { return a->name().substr(0, 5) == "xmlns" && a->value().substr(a->value().length() - 9, 9) == "XMLSchema"; });
  if (it_ns == root->attributes().end())
    return "^$";

  std::string xs_ns = (*it_ns)->name().substr(6);
  if (root->begin_tag() == xs_ns + ":schema")
  {
    std::map<std::string, std::string> refs;
    std::map<std::string, std::string> types;
    std::string re("^" + re_prolog + schema_to_regex(root, xs_ns, refs, types) + re_Misc + "*$");
    // std::cout << re << std::endl; // Mais oui c'est clair
    return re;
  }
  return "^$";
}

std::string schema_to_regex(CompositeElement * s,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  std::string r;
  for (auto c : s->content())
  {
    auto e = dynamic_cast<Element *>(c);
    if (e != nullptr && e->name() == xs_ns + ":element")
      r += element_to_regex(e, xs_ns, refs, types) + "|";

    auto ce = dynamic_cast<CompositeElement *>(c);
    if (ce != nullptr && ce->begin_tag() == xs_ns + ":complexType")
    {
      complexe_type_to_regex(ce, xs_ns, refs, types);
    }
  }
  r = r.substr(0, r.length() - 1);
  return "(" + r + ")";
}

std::string element_to_regex(Element * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  auto it_name = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "name"; });
  if (it_name == e->attributes().end())
  {
    auto it_ref = std::find_if(e->attributes().begin(), e->attributes().end(),
        [](Attribute * a) { return a->name() == "ref"; });
    if (it_ref == e->attributes().end())
      return "";

    auto ref = (*it_ref)->value();
    auto r = refs.find(ref);
    if (r == refs.end())
      return "";
    return r->second;
  }

  auto name = (*it_name)->value();
  const std::string begin("<" + name + "(" + re_S + re_Attr + ")*" + re_blank + ">");
  const std::string end("</" + name + re_blank + ">");

  auto ce = dynamic_cast<CompositeElement *>(e);
  if (ce != nullptr)
  {
    CompositeElement * cce = nullptr;
    if (ce->content().size() >= 1
        && (cce = dynamic_cast<CompositeElement *>(ce->content().front())) != nullptr
        && cce->begin_tag() == xs_ns + ":complexType")
    {
      std::string r(begin + complexe_type_to_regex(cce, xs_ns, refs, types) + end);
      refs[name] = r;
      return r;
    }
  }
  else
  {
    std::string r(begin + simple_element_to_regex(e, xs_ns, refs, types) + end);
    refs[name] = r;
    return r;
  }
  return "";
}

std::string simple_element_to_regex(Element * e,
    std::string xs_ns,
    std::map<std::string, std::string> &,
    std::map<std::string, std::string> & types)
{
  auto it_type = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "type"; });
  if (it_type == e->attributes().end())
    return "";

  auto type = (*it_type)->value();
  if (type == xs_ns + ":string")
    return re_string;
  else if (type == xs_ns + ":date")
    return re_date;

  auto it_ptype = types.find(type);
  if (it_ptype != types.end())
  {
    return "(" + it_ptype->second + ")";
  }

  return "";
}

std::string complexe_type_to_regex(CompositeElement * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  if (e->content().size() < 1)
    return "";

  CompositeElement * ce = dynamic_cast<CompositeElement *>(e->content().front());
  if (ce == nullptr)
    return "";

  bool mixed = false;
  auto it_mixed = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "mixed"; });
  if (it_mixed != e->attributes().end()
      && (*it_mixed)->value() == "true")
    mixed = true;

  std::string s;
  if (ce->begin_tag() == xs_ns + ":choice")
  {
    if (mixed)
      s += re_mixed;
    s += choice_to_regex(ce, xs_ns, refs, types);
    if (mixed)
      s += re_mixed;
  }
  else if (ce->begin_tag() == xs_ns + ":sequence")
  {
    s += sequence_to_regex(ce, xs_ns, refs, types, mixed);
  }

  auto it_name = std::find_if(e->attributes().begin(), e->attributes().end(),
      [](Attribute * a) { return a->name() == "name"; });
  if (it_name != e->attributes().end())
  {
    types[(*it_name)->value()] = s;
  }

  return s;
}

std::string choice_to_regex(CompositeElement * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types)
{
  std::string s;
  for (auto c : e->content())
  {
    auto ce = dynamic_cast<Element *>(c);
    if (ce)
    {
      s += element_to_regex(ce, xs_ns, refs, types);
      if (c != e->content().back())
        s += "|";
    }
  }
  return re_blank + "(" + s + ")" + re_blank;
}

std::string sequence_to_regex(CompositeElement * e,
    std::string xs_ns,
    std::map<std::string, std::string> & refs,
    std::map<std::string, std::string> & types, bool mixed)
{
  std::string s;
  std::string space = mixed ? re_mixed : re_blank;
  for (auto c : e->content())
  {
    auto ce = dynamic_cast<Element *>(c);
    if (ce)
    {
      auto it_maxOccurs = std::find_if(ce->attributes().begin(),
          ce->attributes().end(),
          [](Attribute * a) { return a->name() == "maxOccurs"; });
      std::string reg = element_to_regex(ce, xs_ns, refs, types) + space;
      if (it_maxOccurs != ce->attributes().end())
      {
        int maxOccurs = atoi((*it_maxOccurs)->value().c_str());
        for (int i(0); i < maxOccurs; i++) {
          s += reg;
        }
      }
      else
      {
        s += reg;
      }
    }
  }
  return space + s;
}

<|endoftext|>


<commit_before>#include "../USB.h"
#include "../configuration.h"
#include "../deviceproxy.h"
#include "../usb-pad/padproxy.h"
#include "../usb-mic/audiosourceproxy.h"

#include <sstream>
#include <map>
#include <vector>
#include <string>

#include "ini.h"
#include "config.h"

//libjoyrumble used as an example
//Hopefully PCSX2 has inited all the GTK stuff already
using namespace std;

static std::string usb_path;
std::string IniDir;
std::string LogDir;
const char* iniFile = "USBqemu-wheel.ini";

void SysMessage(const char *fmt, ...)
{
	va_list arglist;

	va_start(arglist, fmt);
	vfprintf(stderr, fmt, arglist);
	va_end(arglist);
}

void CALLBACK USBsetSettingsDir( const char* dir )
{
	fprintf(stderr, "USBsetSettingsDir: %s\n", dir);
	IniDir = dir;
}

void CALLBACK USBsetLogDir( const char* dir )
{
	printf("USBsetLogDir: %s\n", dir);
	LogDir = dir;
}

template<typename T>
bool LoadSettingValue(const std::string& ini, const std::string& section, const char* param, T& value);
template<typename T>
bool SaveSettingValue(const std::string& ini, const std::string& section, const char* param, T& value);

template<>
bool LoadSettingValue(const std::string& ini, const std::string& section, const char* param, std::string& value)
{
	char tmp[4096] = {0};
	INILoadString(ini.c_str(), section.c_str(), param, tmp);
	value = tmp;
	return true;
}

template<>
bool LoadSettingValue(const std::string& ini, const std::string& section, const char* param, int64_t& value)
{
	INILoadUInt(ini.c_str(), section.c_str(), param, (unsigned int *)value);
	return true;
}

template<>
bool SaveSettingValue(const std::string& ini, const std::string& section, const char* param, std::string& value)
{
	INISaveString(ini.c_str(), section.c_str(), param, value.c_str());
	return true;
}

template<>
bool SaveSettingValue(const std::string& ini, const std::string& section, const char* param, int64_t& value)
{
	INISaveUInt(ini.c_str(), section.c_str(), param, (unsigned int)value);
	return true;
}

bool LoadSetting(int port, const std::string& key, CONFIGVARIANT& var)
{
	fprintf(stderr, "USBqemu load \"%s\" from [%s %d]\n", var.name, key.c_str(), port);

	if (key.empty())
		return false;

	std::stringstream section;
	section << key << " " << port;

	std::string ini(IniDir);
	ini.append(iniFile);

	switch(var.type)
	{
		case CONFIG_TYPE_INT:
			return LoadSettingValue(ini, section.str(), var.name, var.intValue);
		//case CONFIG_TYPE_DOUBLE:
		//	return LoadSettingValue(ini, section.str(), var.name, var.doubleValue);
		case CONFIG_TYPE_TCHAR:
			return LoadSettingValue(ini, section.str(), var.name, var.tstrValue);
		case CONFIG_TYPE_CHAR:
			return LoadSettingValue(ini, section.str(), var.name, var.strValue);
		//case CONFIG_TYPE_WCHAR:
		//	return LoadSettingValue(ini, section.str(), var.name, var.wstrValue);
		break;
		default:
			fprintf(stderr, "Invalid config type %d for %s\n", var.type, var.name);
			break;
	};
	return false;
}

/**
 *
 * [devices]
 * portX = pad
 *
 * [pad X]
 * api = joydev
 *
 * [joydev X]
 * button0 = 1
 * button1 = 2
 * ...
 *
 * */
bool SaveSetting(int port, const std::string& key, CONFIGVARIANT& var)
{
	fprintf(stderr, "USBqemu save \"%s\" to [%s %d]\n", var.name, key.c_str(), port);

	if (key.empty())
		return false;

	std::stringstream section;
	section << key << " " << port;

	std::string ini(IniDir);
	ini.append(iniFile);

	switch(var.type)
	{
		case CONFIG_TYPE_INT:
			return SaveSettingValue(ini, section.str(), var.name, var.intValue);
		case CONFIG_TYPE_TCHAR:
			return LoadSettingValue(ini, section.str(), var.name, var.tstrValue);
		case CONFIG_TYPE_CHAR:
			return SaveSettingValue(ini, section.str(), var.name, var.strValue);
		break;
		default:
			fprintf(stderr, "Invalid config type %d for %s\n", var.type, var.name);
			break;
	};
	return false;
}

void SaveConfig() {
	fprintf(stderr, "USB save config\n");
	//char* envptr = getenv("HOME");
	//if(envptr == NULL)
	//	return;
	//char path[1024];
	//snprintf(path, sizeof(path), "%s/.config/PCSX2/inis/USBqemu-wheel.ini", envptr);
	std::string iniPath(IniDir);
	iniPath.append(iniFile);
	const char *path = iniPath.c_str();

	//fprintf(stderr, "%s\n", path);

	INISaveString(path, N_DEVICES, N_DEVICE_PORT0, conf.Port0.c_str());
	INISaveString(path, N_DEVICES, N_DEVICE_PORT1, conf.Port1.c_str());
	INISaveUInt(path, N_DEVICES, N_WHEEL_TYPE0, conf.WheelType[0]);
	INISaveUInt(path, N_DEVICES, N_WHEEL_TYPE1, conf.WheelType[1]);

	for (auto& k : changedAPIs)
	{
		CONFIGVARIANT var(N_DEVICE_API, CONFIG_TYPE_CHAR);
		var.strValue = k.second;
		fprintf(stderr, "Save apis: %s %s\n", k.first.second.c_str(), k.second.c_str());
		SaveSetting(k.first.first, k.first.second, var);
	}
}

void LoadConfig() {
	char tmp[1024] = {0};
	fprintf(stderr, "USB load config\n");
	//char* envptr = getenv("HOME");
	//if(envptr == NULL)
	//	return;
	//char path[1024];
	//sprintf(path, "%s/.config/PCSX2/inis/USBqemu-wheel.ini", envptr);
	std::string iniPath(IniDir);
	iniPath.append(iniFile);
	const char *path = iniPath.c_str();

	INILoadString(path, N_DEVICES, N_DEVICE_PORT0, tmp);
	conf.Port0 = tmp;
	INILoadString(path, N_DEVICES, N_DEVICE_PORT1, tmp);
	conf.Port1 = tmp;
	INILoadUInt(path, N_DEVICES, N_WHEEL_TYPE0, (u32*)&conf.WheelType[0]);
	INILoadUInt(path, N_DEVICES, N_WHEEL_TYPE1, (u32*)&conf.WheelType[1]);

	{
		auto instance = RegisterDevice::instance();
		CONFIGVARIANT tmpVar(N_DEVICE_API, CONFIG_TYPE_CHAR);
		LoadSetting(0, conf.Port0, tmpVar);
		std::string api = tmpVar.strValue;
		auto dev = instance.Device(conf.Port0);

		if (dev && !dev->IsValidAPI(api))
		{
			auto apis = dev->APIs();
			if (!apis.empty())
				api = *apis.begin();
		}

		if(api.size())
			changedAPIs[std::make_pair(0, conf.Port0)] = api;

		LoadSetting(1, conf.Port1, tmpVar);
		api = tmpVar.strValue;

		dev = instance.Device(conf.Port1);
		if (dev && !dev->IsValidAPI(api))
		{
			auto apis = dev->APIs();
			if (!apis.empty())
				api = *apis.begin();
		}

		if(api.size())
			changedAPIs[std::make_pair(1, conf.Port1)] = api;
	}
}
<commit_msg>linux: *SettingValue: change to int32_t<commit_after>#include "../USB.h"
#include "../configuration.h"
#include "../deviceproxy.h"
#include "../usb-pad/padproxy.h"
#include "../usb-mic/audiosourceproxy.h"

#include <sstream>
#include <map>
#include <vector>
#include <string>

#include "ini.h"
#include "config.h"

//libjoyrumble used as an example
//Hopefully PCSX2 has inited all the GTK stuff already
using namespace std;

static std::string usb_path;
std::string IniDir;
std::string LogDir;
const char* iniFile = "USBqemu-wheel.ini";

void SysMessage(const char *fmt, ...)
{
	va_list arglist;

	va_start(arglist, fmt);
	vfprintf(stderr, fmt, arglist);
	va_end(arglist);
}

void CALLBACK USBsetSettingsDir( const char* dir )
{
	fprintf(stderr, "USBsetSettingsDir: %s\n", dir);
	IniDir = dir;
}

void CALLBACK USBsetLogDir( const char* dir )
{
	printf("USBsetLogDir: %s\n", dir);
	LogDir = dir;
}

template<typename T>
bool LoadSettingValue(const std::string& ini, const std::string& section, const char* param, T& value);
template<typename T>
bool SaveSettingValue(const std::string& ini, const std::string& section, const char* param, T& value);

template<>
bool LoadSettingValue(const std::string& ini, const std::string& section, const char* param, std::string& value)
{
	char tmp[4096] = {0};
	INILoadString(ini.c_str(), section.c_str(), param, tmp);
	value = tmp;
	return true;
}

template<>
bool LoadSettingValue(const std::string& ini, const std::string& section, const char* param, int32_t& value)
{
	INILoadUInt(ini.c_str(), section.c_str(), param, (unsigned int *)value);
	return true;
}

template<>
bool SaveSettingValue(const std::string& ini, const std::string& section, const char* param, std::string& value)
{
	INISaveString(ini.c_str(), section.c_str(), param, value.c_str());
	return true;
}

template<>
bool SaveSettingValue(const std::string& ini, const std::string& section, const char* param, int32_t& value)
{
	INISaveUInt(ini.c_str(), section.c_str(), param, (unsigned int)value);
	return true;
}

bool LoadSetting(int port, const std::string& key, CONFIGVARIANT& var)
{
	fprintf(stderr, "USBqemu load \"%s\" from [%s %d]\n", var.name, key.c_str(), port);

	if (key.empty())
		return false;

	std::stringstream section;
	section << key << " " << port;

	std::string ini(IniDir);
	ini.append(iniFile);

	switch(var.type)
	{
		case CONFIG_TYPE_INT:
			return LoadSettingValue(ini, section.str(), var.name, var.intValue);
		//case CONFIG_TYPE_DOUBLE:
		//	return LoadSettingValue(ini, section.str(), var.name, var.doubleValue);
		case CONFIG_TYPE_TCHAR:
			return LoadSettingValue(ini, section.str(), var.name, var.tstrValue);
		case CONFIG_TYPE_CHAR:
			return LoadSettingValue(ini, section.str(), var.name, var.strValue);
		//case CONFIG_TYPE_WCHAR:
		//	return LoadSettingValue(ini, section.str(), var.name, var.wstrValue);
		break;
		default:
			fprintf(stderr, "Invalid config type %d for %s\n", var.type, var.name);
			break;
	};
	return false;
}

/**
 *
 * [devices]
 * portX = pad
 *
 * [pad X]
 * api = joydev
 *
 * [joydev X]
 * button0 = 1
 * button1 = 2
 * ...
 *
 * */
bool SaveSetting(int port, const std::string& key, CONFIGVARIANT& var)
{
	fprintf(stderr, "USBqemu save \"%s\" to [%s %d]\n", var.name, key.c_str(), port);

	if (key.empty())
		return false;

	std::stringstream section;
	section << key << " " << port;

	std::string ini(IniDir);
	ini.append(iniFile);

	switch(var.type)
	{
		case CONFIG_TYPE_INT:
			return SaveSettingValue(ini, section.str(), var.name, var.intValue);
		case CONFIG_TYPE_TCHAR:
			return LoadSettingValue(ini, section.str(), var.name, var.tstrValue);
		case CONFIG_TYPE_CHAR:
			return SaveSettingValue(ini, section.str(), var.name, var.strValue);
		break;
		default:
			fprintf(stderr, "Invalid config type %d for %s\n", var.type, var.name);
			break;
	};
	return false;
}

void SaveConfig() {
	fprintf(stderr, "USB save config\n");
	//char* envptr = getenv("HOME");
	//if(envptr == NULL)
	//	return;
	//char path[1024];
	//snprintf(path, sizeof(path), "%s/.config/PCSX2/inis/USBqemu-wheel.ini", envptr);
	std::string iniPath(IniDir);
	iniPath.append(iniFile);
	const char *path = iniPath.c_str();

	//fprintf(stderr, "%s\n", path);

	INISaveString(path, N_DEVICES, N_DEVICE_PORT0, conf.Port0.c_str());
	INISaveString(path, N_DEVICES, N_DEVICE_PORT1, conf.Port1.c_str());
	INISaveUInt(path, N_DEVICES, N_WHEEL_TYPE0, conf.WheelType[0]);
	INISaveUInt(path, N_DEVICES, N_WHEEL_TYPE1, conf.WheelType[1]);

	for (auto& k : changedAPIs)
	{
		CONFIGVARIANT var(N_DEVICE_API, CONFIG_TYPE_CHAR);
		var.strValue = k.second;
		fprintf(stderr, "Save apis: %s %s\n", k.first.second.c_str(), k.second.c_str());
		SaveSetting(k.first.first, k.first.second, var);
	}
}

void LoadConfig() {
	char tmp[1024] = {0};
	fprintf(stderr, "USB load config\n");
	//char* envptr = getenv("HOME");
	//if(envptr == NULL)
	//	return;
	//char path[1024];
	//sprintf(path, "%s/.config/PCSX2/inis/USBqemu-wheel.ini", envptr);
	std::string iniPath(IniDir);
	iniPath.append(iniFile);
	const char *path = iniPath.c_str();

	INILoadString(path, N_DEVICES, N_DEVICE_PORT0, tmp);
	conf.Port0 = tmp;
	INILoadString(path, N_DEVICES, N_DEVICE_PORT1, tmp);
	conf.Port1 = tmp;
	INILoadUInt(path, N_DEVICES, N_WHEEL_TYPE0, (u32*)&conf.WheelType[0]);
	INILoadUInt(path, N_DEVICES, N_WHEEL_TYPE1, (u32*)&conf.WheelType[1]);

	{
		auto instance = RegisterDevice::instance();
		CONFIGVARIANT tmpVar(N_DEVICE_API, CONFIG_TYPE_CHAR);
		LoadSetting(0, conf.Port0, tmpVar);
		std::string api = tmpVar.strValue;
		auto dev = instance.Device(conf.Port0);

		if (dev && !dev->IsValidAPI(api))
		{
			auto apis = dev->APIs();
			if (!apis.empty())
				api = *apis.begin();
		}

		if(api.size())
			changedAPIs[std::make_pair(0, conf.Port0)] = api;

		LoadSetting(1, conf.Port1, tmpVar);
		api = tmpVar.strValue;

		dev = instance.Device(conf.Port1);
		if (dev && !dev->IsValidAPI(api))
		{
			auto apis = dev->APIs();
			if (!apis.empty())
				api = *apis.begin();
		}

		if(api.size())
			changedAPIs[std::make_pair(1, conf.Port1)] = api;
	}
}
<|endoftext|>


<commit_before>#include <iostream>
using namespace std;

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include "localFileList.h"
#include "filePattern.h"

extern "C" {
#include "logger.h"
}

LocalFileList::LocalFileList(FilePattern *excludeFilePattern) {
	this->paths = (char **) malloc(sizeof(char *) * 100);
	this->sizes = (uint64_t *) malloc(sizeof(uint64_t) * 100);
	this->allocCount = 100;
	this->count = 0;
	this->excludeFilePattern = excludeFilePattern;
}

LocalFileList::~LocalFileList() {
	for (uint32_t i=0;i<this->count;i++) {
		this->paths[i]=NULL;
	}

	free(this->sizes);
	free(this->paths);

	this->excludeFilePattern = NULL;
}

void LocalFileList::add(char *path, uint64_t size) {
	if (this->excludeFilePattern && this->excludeFilePattern->matches(path)) {
		LOG(LOG_DBG, "[File List] Excluded %s", path);
		return;
	}

	this->paths[this->count] = path;
	this->sizes[this->count] = size;
	this->count++;
	if (this->count>=this->allocCount) {
		this->allocCount+=100;
		this->paths = (char **) realloc(this->paths, sizeof(char *) * this->allocCount);
		this->sizes = (uint64_t *) realloc(this->sizes, sizeof(uint64_t) * this->allocCount);
	}
}

void LocalFileList::recurseIn(char *path, char *prefix) {
	uint64_t len = strlen(prefix) + strlen(path)+2;
	char *toOpen = (char *) malloc(len);
	bzero(toOpen, len);
	strcat(toOpen, prefix);
	strcat(toOpen, path);

	DIR *dirp = opendir(toOpen);

  struct dirent *dp = NULL;
	while ((dp = readdir(dirp))) {
		if (dp->d_type == DT_REG) {
			uint64_t len = (strlen(path)+strlen(dp->d_name)+2);
			char *fullName = (char *) malloc((size_t)len);
			sprintf(fullName, "%s/%s", path, dp->d_name);

			char *statName = (char *) malloc(strlen(prefix)+strlen(fullName)+2);
			sprintf(statName, "%s%s", prefix, fullName);

			struct stat fileInfo;
			if (lstat(statName, &fileInfo)<0) {
				LOG(LOG_WARN, "[File List] WARNING: cannot stat file: %s", statName);
			} else {
				this->add(fullName, (uint64_t) fileInfo.st_size);
			}
			free(statName);

		} else if (dp->d_type == DT_DIR) {
			if (strcmp(dp->d_name, ".")!=0 && strcmp(dp->d_name, "..")!=0) {
				char *_path= (char *) malloc(strlen(path)+strlen(dp->d_name)+2);
				sprintf(_path, "%s/%s", path, dp->d_name);
				this->recurseIn(_path, prefix);
				free(_path);
			}
		}
	}

	free(toOpen);

	closedir(dirp);
}

uint64_t LocalFileList::calculateTotalSize() {
	uint64_t totalSize=0;
	for (uint32_t i=0;i<this->count;i++) {
		totalSize+=this->sizes[i];
	}
	return totalSize;
}

<commit_msg>no, dup but don't sprintf<commit_after>#include <iostream>
using namespace std;

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include "localFileList.h"
#include "filePattern.h"

extern "C" {
#include "logger.h"
}

LocalFileList::LocalFileList(FilePattern *excludeFilePattern) {
	this->paths = (char **) malloc(sizeof(char *) * 100);
	this->sizes = (uint64_t *) malloc(sizeof(uint64_t) * 100);
	this->allocCount = 100;
	this->count = 0;
	this->excludeFilePattern = excludeFilePattern;
}

LocalFileList::~LocalFileList() {
	for (uint32_t i=0;i<this->count;i++) {
		free(this->paths[i]);
	}

	free(this->sizes);
	free(this->paths);

	this->excludeFilePattern = NULL;
}

void LocalFileList::add(char *path, uint64_t size) {
	if (this->excludeFilePattern && this->excludeFilePattern->matches(path)) {
		LOG(LOG_DBG, "[File List] Excluded %s", path);
		return;
	}

	this->paths[this->count] = strdup(path);
	this->sizes[this->count] = size;
	this->count++;
	if (this->count>=this->allocCount) {
		this->allocCount+=100;
		this->paths = (char **) realloc(this->paths, sizeof(char *) * this->allocCount);
		this->sizes = (uint64_t *) realloc(this->sizes, sizeof(uint64_t) * this->allocCount);
	}
}

void LocalFileList::recurseIn(char *path, char *prefix) {
	uint64_t len = strlen(prefix) + strlen(path)+2;
	char *toOpen = (char *) malloc(len);
	toOpen[0]=0;
	strcat(toOpen, prefix);
	strcat(toOpen, path);

	DIR *dirp = opendir(toOpen);

  struct dirent *dp = NULL;
	while ((dp = readdir(dirp))) {
		if (dp->d_type == DT_REG) {
			uint64_t len = (strlen(path)+strlen(dp->d_name)+2);
			char *fullName = (char *) malloc((size_t)len);
			fullName[0]=0;
			strcat(fullName, path);
			strcat(fullName, "/");
			strcat(fullName, dp->d_name);

			char *statName = (char *) malloc(strlen(prefix)+strlen(fullName)+2);
			statName[0]=0;
			strcat(statName, prefix);
			strcat(statName, fullName);

			struct stat fileInfo;
			if (lstat(statName, &fileInfo)<0) {
				LOG(LOG_WARN, "[File List] WARNING: cannot stat file: %s", statName);
			} else {
				this->add(fullName, (uint64_t) fileInfo.st_size);
			}
			free(fullName);
			free(statName);

		} else if (dp->d_type == DT_DIR) {
			if (strcmp(dp->d_name, ".")!=0 && strcmp(dp->d_name, "..")!=0) {
				char *_path= (char *) malloc(strlen(path)+strlen(dp->d_name)+2);
				_path[0]=0;
				strcat(_path, path);
				strcat(_path, "/");
				strcat(_path, dp->d_name);
				this->recurseIn(_path, prefix);
				free(_path);
			}
		}
	}

	free(toOpen);

	closedir(dirp);
}

uint64_t LocalFileList::calculateTotalSize() {
	uint64_t totalSize=0;
	for (uint32_t i=0;i<this->count;i++) {
		totalSize+=this->sizes[i];
	}
	return totalSize;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: macrodlg.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: kz $ $Date: 2004-07-23 12:05:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
//
#ifndef _MACRODLG_HXX
#define _MACRODLG_HXX

#ifndef _SVHEADER_HXX
#include <svheader.hxx>
#endif

#include <bastype2.hxx>
#include <bastype3.hxx>

#ifndef _BASEDLGS_HXX //autogen
#include <sfx2/basedlgs.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#define MACRO_CLOSE         10
#define MACRO_OK_RUN        11
#define MACRO_NEW           12
#define MACRO_EDIT          14
#define MACRO_ORGANIZE      15
#define MACRO_ASSIGN        16

#define MACROCHOOSER_ALL            1
#define MACROCHOOSER_CHOOSEONLY     2
#define MACROCHOOSER_RECORDING      3

class BasicManager;

class MacroChooser : public SfxModalDialog
{
private:
    FixedText               aMacroNameTxt;
    Edit                    aMacroNameEdit;
    FixedText               aMacrosInTxt;
    String                  aMacrosInTxtBaseStr;
    SvTreeListBox           aMacroBox;
    FixedText               aMacroFromTxT;
    FixedText               aMacrosSaveInTxt;
    BasicTreeListBox        aBasicBox;

    PushButton              aRunButton;
    CancelButton            aCloseButton;
    PushButton              aAssignButton;
    PushButton              aEditButton;
    PushButton              aNewDelButton;
    PushButton              aOrganizeButton;
    HelpButton              aHelpButton;
    PushButton              aNewLibButton;
    PushButton              aNewModButton;

    BOOL                bNewDelIsDel;
    BOOL                bForceStoreBasic;

    USHORT              nMode;

    DECL_LINK( MacroSelectHdl, SvTreeListBox * );
    DECL_LINK( MacroDoubleClickHdl, SvTreeListBox * );
    DECL_LINK( BasicSelectHdl, SvTreeListBox * );
    DECL_LINK( EditModifyHdl, Edit * );
    DECL_LINK( ButtonHdl, Button * );

    void                CheckButtons();
    void                SaveSetCurEntry( SvTreeListBox& rBox, SvLBoxEntry* pEntry );
    void                UpdateFields();

    void                EnableButton( Button& rButton, BOOL bEnable );

    String              GetInfo( SbxVariable* pVar );

    void                StoreMacroDescription();
    void                RestoreMacroDescription();

public:
                        MacroChooser( Window* pParent, BOOL bCreateEntries = TRUE );
                        ~MacroChooser();

    SbMethod*           GetMacro();
    void                DeleteMacro();
    SbMethod*           CreateMacro();

    virtual short       Execute();

    void                SetMode( USHORT nMode );
    USHORT              GetMode() const { return nMode; }
};

#endif  // _MACRODLG_HXX
<commit_msg>INTEGRATION: CWS ooo19126 (1.7.140); FILE MERGED 2005/09/05 13:55:42 rt 1.7.140.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: macrodlg.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 20:06:02 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
//
#ifndef _MACRODLG_HXX
#define _MACRODLG_HXX

#ifndef _SVHEADER_HXX
#include <svheader.hxx>
#endif

#include <bastype2.hxx>
#include <bastype3.hxx>

#ifndef _BASEDLGS_HXX //autogen
#include <sfx2/basedlgs.hxx>
#endif

#ifndef _SV_FIXED_HXX //autogen
#include <vcl/fixed.hxx>
#endif

#ifndef _SV_BUTTON_HXX //autogen
#include <vcl/button.hxx>
#endif

#define MACRO_CLOSE         10
#define MACRO_OK_RUN        11
#define MACRO_NEW           12
#define MACRO_EDIT          14
#define MACRO_ORGANIZE      15
#define MACRO_ASSIGN        16

#define MACROCHOOSER_ALL            1
#define MACROCHOOSER_CHOOSEONLY     2
#define MACROCHOOSER_RECORDING      3

class BasicManager;

class MacroChooser : public SfxModalDialog
{
private:
    FixedText               aMacroNameTxt;
    Edit                    aMacroNameEdit;
    FixedText               aMacrosInTxt;
    String                  aMacrosInTxtBaseStr;
    SvTreeListBox           aMacroBox;
    FixedText               aMacroFromTxT;
    FixedText               aMacrosSaveInTxt;
    BasicTreeListBox        aBasicBox;

    PushButton              aRunButton;
    CancelButton            aCloseButton;
    PushButton              aAssignButton;
    PushButton              aEditButton;
    PushButton              aNewDelButton;
    PushButton              aOrganizeButton;
    HelpButton              aHelpButton;
    PushButton              aNewLibButton;
    PushButton              aNewModButton;

    BOOL                bNewDelIsDel;
    BOOL                bForceStoreBasic;

    USHORT              nMode;

    DECL_LINK( MacroSelectHdl, SvTreeListBox * );
    DECL_LINK( MacroDoubleClickHdl, SvTreeListBox * );
    DECL_LINK( BasicSelectHdl, SvTreeListBox * );
    DECL_LINK( EditModifyHdl, Edit * );
    DECL_LINK( ButtonHdl, Button * );

    void                CheckButtons();
    void                SaveSetCurEntry( SvTreeListBox& rBox, SvLBoxEntry* pEntry );
    void                UpdateFields();

    void                EnableButton( Button& rButton, BOOL bEnable );

    String              GetInfo( SbxVariable* pVar );

    void                StoreMacroDescription();
    void                RestoreMacroDescription();

public:
                        MacroChooser( Window* pParent, BOOL bCreateEntries = TRUE );
                        ~MacroChooser();

    SbMethod*           GetMacro();
    void                DeleteMacro();
    SbMethod*           CreateMacro();

    virtual short       Execute();

    void                SetMode( USHORT nMode );
    USHORT              GetMode() const { return nMode; }
};

#endif  // _MACRODLG_HXX
<|endoftext|>


<commit_before>#include <cstdint>
#include <cassert>

#include <immintrin.h>
#include <x86intrin.h>

#define packed_dword(x) _mm512_set1_epi32(x)
#define packed_byte(x) packed_dword((x) | ((x) << 8) | ((x) << 16) | ((x) << 24))

namespace base64 {

    namespace avx512 {

        namespace precalc {

            static uint8_t valid[256];
            static uint32_t lookup_0[256];
            static uint32_t lookup_1[256];
            static uint32_t lookup_2[256];
            static uint32_t lookup_3[256];
        }

        void initalize_lookup() {

            using namespace precalc;

            for (int i=0; i < 256; i++) {
                lookup_0[i] = 0x80000000;
                lookup_1[i] = 0x80000000;
                lookup_2[i] = 0x80000000;
                lookup_3[i] = 0x80000000;
                valid[i] = 0;
            }

            for (int i=0; i < 64; i++) {
                const uint32_t val = static_cast<uint8_t>(base64::lookup[i]);

                valid[val] = 1;
                lookup_0[val] = i;
                lookup_1[val] = i << 1*6;
                lookup_2[val] = i << 2*6;
                lookup_3[val] = i << 3*6;
            }
        }

        void dump(__m512i v) {
            static uint8_t buf[64];

            _mm512_storeu_si512(reinterpret_cast<__m512i*>(buf), v);

            for (int i=0; i < 64; i++) {
                printf("%02x ", buf[i]);
            }

            putchar('\n');
        }

        void report_exception(const __m512i erroneous_input) {

            // an error occurs just once, peformance is not cruical

            uint8_t tmp[64];
            _mm512_storeu_si512(reinterpret_cast<__m512*>(tmp), erroneous_input);

            for (unsigned i=0; i < 64; i++) {
                if (!precalc::valid[tmp[i]]) {
                    throw invalid_input(i, tmp[i]);
                }
            }
        }

        __m512i lookup_gather(const __m512i input) {

            const __m512i b0 = _mm512_and_si512(input, packed_dword(0x000000ff));
            const __m512i b1 = _mm512_and_si512(_mm512_srli_epi32(input, 1*8), packed_dword(0x000000ff));
            const __m512i b2 = _mm512_and_si512(_mm512_srli_epi32(input, 2*8), packed_dword(0x000000ff));
            const __m512i b3 = _mm512_and_si512(_mm512_srli_epi32(input, 3*8), packed_dword(0x000000ff));

            // do lookup
            const __m512i r0 = _mm512_i32gather_epi32(b0, (const int*)precalc::lookup_0, 4);
            const __m512i r1 = _mm512_i32gather_epi32(b1, (const int*)precalc::lookup_1, 4);
            const __m512i r2 = _mm512_i32gather_epi32(b2, (const int*)precalc::lookup_2, 4);
            const __m512i r3 = _mm512_i32gather_epi32(b3, (const int*)precalc::lookup_3, 4);
            const __m512i translated = _mm512_or_si512(r0,
                                       _mm512_or_si512(r1,
                                       _mm512_or_si512(r2, r3)));

            const uint16_t mask = _mm512_cmplt_epi32_mask(translated, _mm512_set1_epi32(0));
            if (mask) {
                report_exception(input);
            }

            return translated;
        }

        // returns packed (a[i] >= lo and a[i] <= hi) ? 0xff : 0x00;
        // assertion a[i] < 0x80

        __m512i _mm512_range_mask(const __m512i a, const __m512i lo, const __m512i hi) {

            const __m512i L = _mm512_add_epi32(a, lo);
            const __m512i H = _mm512_add_epi32(a, hi);

            const __m512i MSB = _mm512_and_epi32(_mm512_andnot_epi32(H, L), packed_byte(0x80));

            // MSB | (MSB - (MSB >> 7))
            return _mm512_or_si512(MSB, _mm512_sub_epi32(MSB, _mm512_srli_epi32(MSB, 7)));
        }

        __m512i lookup_comparisons(const __m512i input) {

            // we operate on lower 7 bits, as all values with 8th bit set are invalid
            const __m512i in = _mm512_and_si512(input, packed_byte(0x7f));

#define GET_RANGE_SHIFT(shift, lo, hi) \
            _mm512_and_si512(packed_byte(uint8_t(shift)), \
                             _mm512_range_mask(in, packed_byte(0x80 - (lo)), packed_byte(0x80 - (hi))))

            // shift for range 'A' - 'Z'
            const __m512i range_AZ = GET_RANGE_SHIFT(-65, 'A', 'Z' + 1);

            // shift for range 'a' - 'z'
            const __m512i range_az = GET_RANGE_SHIFT(-71, 'a', 'z' + 1);

            // shift for range '0' - '9'
            const __m512i range_09 = GET_RANGE_SHIFT(4, '0', '9' + 1);

            // shift for character '+'
            const __m512i char_plus = GET_RANGE_SHIFT(19, '+', '+' + 1);

            // shift for character '/'
            const __m512i char_slash = GET_RANGE_SHIFT(16, '/', '/' + 1);

            // merge partial results

            const __m512i shift = _mm512_or_si512(range_AZ,
                                  _mm512_or_si512(range_az,
                                  _mm512_or_si512(range_09,
                                  _mm512_or_si512(char_plus, char_slash))));

            // a paddb equivalent
            const __m512i shift06 = _mm512_and_si512(shift, packed_byte(0x7f));
            const __m512i shift7  = _mm512_and_si512(shift, packed_byte(0x80));
            const __m512i result  = _mm512_xor_si512(_mm512_add_epi32(in, shift06), shift7);

            // validation
            const __m512i non_zero_7lower = _mm512_add_epi32(shift06, packed_byte(0x7f));
#if 1
            /*  7 lower bits of shift are non-zero
                | 7th bit of shift is non-zero
                | | 7th bit of inoput is non-zero (extended ASCII)
                | | |
                a b c r
                0 0 0 1
                0 0 1 1
                0 1 0 0
                0 1 1 1
                1 0 0 0
                1 0 1 1
                1 1 0 0
                1 1 1 1

                expression = ~(a | b) | c

            */
            // we're use 7th bit of each byte
            const __m512i valid = _mm512_ternarylogic_epi32(in, shift, non_zero_7lower, 0xab);

#else       // a reference implementation
            // non-zero byte in shift -- 7th bit is set
            const __m512i non_zero = _mm512_or_si512(shift, non_zero_7lower);

            // 7th bit marks error - either shift is zero or byte outside standard ASCII
            const __m512i valid = _mm512_or_si512(input, _mm512_xor_si512(non_zero, packed_byte(0x80)));
#endif
            const __mmask16 mask = _mm512_test_epi32_mask(valid, packed_byte(0x80));
            if (mask) {
                report_exception(input);
            }

            return result;
        }

    } // namespace avx512bw

} // namespace base64

#undef packed_dword
<commit_msg>base64 decode AVX512F: ternary logic, some tweaks<commit_after>#include <cstdint>
#include <cassert>

#include <immintrin.h>
#include <x86intrin.h>

#define packed_dword(x) _mm512_set1_epi32(x)
#define packed_byte(x) packed_dword((x) | ((x) << 8) | ((x) << 16) | ((x) << 24))

namespace base64 {

    namespace avx512 {

        namespace precalc {

            static uint8_t valid[256];
            static uint32_t lookup_0[256];
            static uint32_t lookup_1[256];
            static uint32_t lookup_2[256];
            static uint32_t lookup_3[256];
        }

        void initalize_lookup() {

            using namespace precalc;

            for (int i=0; i < 256; i++) {
                lookup_0[i] = 0x80000000;
                lookup_1[i] = 0x80000000;
                lookup_2[i] = 0x80000000;
                lookup_3[i] = 0x80000000;
                valid[i] = 0;
            }

            for (int i=0; i < 64; i++) {
                const uint32_t val = static_cast<uint8_t>(base64::lookup[i]);

                valid[val] = 1;
                lookup_0[val] = i;
                lookup_1[val] = i << 1*6;
                lookup_2[val] = i << 2*6;
                lookup_3[val] = i << 3*6;
            }
        }

        void dump(__m512i v) {
            static uint8_t buf[64];

            _mm512_storeu_si512(reinterpret_cast<__m512i*>(buf), v);

            for (int i=0; i < 64; i++) {
                printf("%02x ", buf[i]);
            }

            putchar('\n');
        }

        void report_exception(const __m512i erroneous_input) {

            // an error occurs just once, peformance is not cruical

            uint8_t tmp[64];
            _mm512_storeu_si512(reinterpret_cast<__m512*>(tmp), erroneous_input);

            for (unsigned i=0; i < 64; i++) {
                if (!precalc::valid[tmp[i]]) {
                    throw invalid_input(i, tmp[i]);
                }
            }
        }

        __m512i lookup_gather(const __m512i input) {

            const __m512i b0 = _mm512_and_si512(input, packed_dword(0x000000ff));
            const __m512i b1 = _mm512_and_si512(_mm512_srli_epi32(input, 1*8), packed_dword(0x000000ff));
            const __m512i b2 = _mm512_and_si512(_mm512_srli_epi32(input, 2*8), packed_dword(0x000000ff));
            const __m512i b3 = _mm512_and_si512(_mm512_srli_epi32(input, 3*8), packed_dword(0x000000ff));

            // do lookup
            const __m512i r0 = _mm512_i32gather_epi32(b0, (const int*)precalc::lookup_0, 4);
            const __m512i r1 = _mm512_i32gather_epi32(b1, (const int*)precalc::lookup_1, 4);
            const __m512i r2 = _mm512_i32gather_epi32(b2, (const int*)precalc::lookup_2, 4);
            const __m512i r3 = _mm512_i32gather_epi32(b3, (const int*)precalc::lookup_3, 4);
            const __m512i translated = _mm512_or_si512(r0,
                                       _mm512_or_si512(r1,
                                       _mm512_or_si512(r2, r3)));

            const uint16_t mask = _mm512_cmplt_epi32_mask(translated, _mm512_set1_epi32(0));
            if (mask) {
                report_exception(input);
            }

            return translated;
        }

        // returns packed (a[i] >= lo and a[i] <= hi) ? 0x7f : 0x00;
        // assertion a[i] < 0x80
        __m512i _mm512_range_mask_7bit(const __m512i a, const __m512i lo, const __m512i hi) {

            const __m512i L = _mm512_add_epi32(a, lo);
            const __m512i H = _mm512_add_epi32(a, hi);

            /*
                MSB  H   L  |  R
                 0   0   0  |  0
                 0   0   1  |  0
                 0   1   0  |  0
                 0   1   1  |  0
                 1   0   0  |  0
                 1   0   1  |  1
                 1   1   0  |  0
                 1   1   1  |  0
            */

#if 0
            const __m512i MSB = _mm512_and_epi32(_mm512_andnot_epi32(H, L), packed_byte(0x80));
#else
            const __m512i MSB = _mm512_ternarylogic_epi32(packed_byte(0x80), H, L, 0x20);
#endif
            // MSB | (MSB - (MSB >> 7))
            return _mm512_sub_epi32(MSB, _mm512_srli_epi32(MSB, 7));
        }

        // returns packed (a[i] >= lo and a[i] <= hi) ? 0xff : 0x00;
        // assertion a[i] < 0x80
        __m512i _mm512_range_mask_8bit(const __m512i a, const __m512i lo, const __m512i hi) {

            const __m512i L = _mm512_add_epi32(a, lo);
            const __m512i H = _mm512_add_epi32(a, hi);

            const __m512i MSB = _mm512_ternarylogic_epi32(packed_byte(0x80), H, L, 0x20);

            // MSB | (MSB - (MSB >> 7))
            return _mm512_or_si512(MSB, _mm512_sub_epi32(MSB, _mm512_srli_epi32(MSB, 7)));
        }

        // returns packed (a[i] >= lo and a[i] <= hi) ? 0x04 : 0x00;
        // assertion a[i] < 0x80
        __m512i _mm512_range_3rd_bit(const __m512i a, const __m512i lo, const __m512i hi) {

            const __m512i L = _mm512_add_epi32(a, lo);
            const __m512i H = _mm512_add_epi32(a, hi);

            const __m512i MSB = _mm512_ternarylogic_epi32(packed_byte(0x80), H, L, 0x20);

            return _mm512_srli_epi32(MSB, 5);
        }

        __m512i lookup_comparisons(const __m512i input) {

            // we operate on lower 7 bits, as all values with 8th bit set are invalid
            const __m512i in = _mm512_and_si512(input, packed_byte(0x7f));

#define GET_RANGE_SHIFT_7BIT(shift, lo, hi) \
            _mm512_and_si512(packed_byte(uint8_t(shift)), \
                             _mm512_range_mask_7bit(in, packed_byte(0x80 - (lo)), packed_byte(0x80 - (hi))))

#define GET_RANGE_SHIFT_8BIT(shift, lo, hi) \
            _mm512_and_si512(packed_byte(uint8_t(shift)), \
                             _mm512_range_mask_8bit(in, packed_byte(0x80 - (lo)), packed_byte(0x80 - (hi))))

#define GET_RANGE_SHIFT_3RD_BIT(lo, hi) \
            _mm512_range_3rd_bit(in, packed_byte(0x80 - (lo)), packed_byte(0x80 - (hi)))

            // shift for range 'A' - 'Z'
            const __m512i range_AZ = GET_RANGE_SHIFT_8BIT(-65, 'A', 'Z' + 1);

            // shift for range 'a' - 'z'
            const __m512i range_az = GET_RANGE_SHIFT_8BIT(-71, 'a', 'z' + 1);

            // shift for range '0' - '9'
            const __m512i range_09 = GET_RANGE_SHIFT_3RD_BIT('0', '9' + 1); // shift = 4

            // shift for character '+'
            const __m512i char_plus = GET_RANGE_SHIFT_7BIT(19, '+', '+' + 1);

            // shift for character '/'
            const __m512i char_slash = GET_RANGE_SHIFT_7BIT(16, '/', '/' + 1);

            // merge partial results
            /*
                a b c a|b|c
                0 0 0   0
                0 0 1   1
                0 1 0   1
                0 1 1   1
                1 0 0   1
                1 0 1   1
                1 1 0   1
                1 1 1   1
            */
#if 0
            const __m512i shift = _mm512_or_si512(range_AZ,
                                  _mm512_or_si512(range_az,
                                  _mm512_or_si512(range_09,
                                  _mm512_or_si512(char_plus, char_slash))));
#else
            const __m512i tmp   = _mm512_ternarylogic_epi32(range_AZ, range_az, range_09, 0xfe);
            const __m512i shift = _mm512_ternarylogic_epi32(char_plus, char_slash, tmp, 0xfe);
#endif

            // a paddb equivalent
            const __m512i shift06 = _mm512_and_si512(shift, packed_byte(0x7f));
            const __m512i shift7  = _mm512_and_si512(shift, packed_byte(0x80));
            const __m512i result  = _mm512_xor_si512(_mm512_add_epi32(in, shift06), shift7);

            // validation
            const __m512i non_zero_7lower = _mm512_add_epi32(shift06, packed_byte(0x7f));
#if 1
            /*  7 lower bits of shift are non-zero
                | 7th bit of shift is non-zero
                | | 7th bit of inoput is non-zero (extended ASCII)
                | | |
                a b c r
                0 0 0 1
                0 0 1 1
                0 1 0 0
                0 1 1 1
                1 0 0 0
                1 0 1 1
                1 1 0 0
                1 1 1 1

                expression = ~(a | b) | c

            */
            // we're use 7th bit of each byte
            const __m512i valid = _mm512_ternarylogic_epi32(in, shift, non_zero_7lower, 0xab);

#else       // a reference implementation
            // non-zero byte in shift -- 7th bit is set
            const __m512i non_zero = _mm512_or_si512(shift, non_zero_7lower);

            // 7th bit marks error - either shift is zero or byte outside standard ASCII
            const __m512i valid = _mm512_or_si512(input, _mm512_xor_si512(non_zero, packed_byte(0x80)));
#endif
            const __mmask16 mask = _mm512_test_epi32_mask(valid, packed_byte(0x80));
            if (mask) {
                report_exception(input);
            }

            return result;
        }

    } // namespace avx512bw

} // namespace base64

#undef packed_dword
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2007. 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)

#include <libtorrent/extensions.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/lazy_entry.hpp>
#include <libtorrent/peer_request.hpp>
#include <libtorrent/disk_buffer_holder.hpp>
#include <libtorrent/bitfield.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

namespace
{
  struct peer_plugin_wrap : peer_plugin, wrapper<peer_plugin>
  {
      void add_handshake(entry& e)
      {
          if (override f = this->get_override("add_handshake"))
              e = call<entry>(f.ptr(), e);
          else
              peer_plugin::add_handshake(e);
      }

      void default_add_handshake(entry& e)
      {
          this->peer_plugin::add_handshake(e);
      }

      bool on_handshake(char const* reserved_bits)
      {
          if (override f = this->get_override("on_handshake"))
              return f();
          else
              return peer_plugin::on_handshake(reserved_bits);
      }

      bool default_on_handshake(char const* reserved_bits)
      {
          return this->peer_plugin::on_handshake(reserved_bits);
      }

      bool on_extension_handshake(lazy_entry const& e)
      {
          if (override f = this->get_override("on_extension_handshake"))
              return f(e);
          else
              return peer_plugin::on_extension_handshake(e);
      }

      bool default_on_extension_handshake(lazy_entry const& e)
      {
          return this->peer_plugin::on_extension_handshake(e);
      }

      bool on_choke()
      {
          if (override f = this->get_override("on_choke"))
              return f();
          else
              return peer_plugin::on_choke();
      }

      bool default_on_choke()
      {
          return this->peer_plugin::on_choke();
      }

      bool on_unchoke()
      {
          if (override f = this->get_override("on_unchoke"))
              return f();
          else
              return peer_plugin::on_unchoke();
      }

      bool default_on_unchoke()
      {
          return this->peer_plugin::on_unchoke();
      }

      bool on_interested()
      {
          if (override f = this->get_override("on_interested"))
              return f();
          else
              return peer_plugin::on_interested();
      }

      bool default_on_interested()
      {
          return this->peer_plugin::on_interested();
      }

      bool on_not_interested()
      {
          if (override f = this->get_override("on_not_interested"))
              return f();
          else
              return peer_plugin::on_not_interested();
      }

      bool default_on_not_interested()
      {
          return this->peer_plugin::on_not_interested();
      }

      bool on_have(int index)
      {
          if (override f = this->get_override("on_have"))
              return f(index);
          else
              return peer_plugin::on_have(index);
      }

      bool default_on_have(int index)
      {
          return this->peer_plugin::on_have(index);
      }

      bool on_bitfield(list _bf)
      {
          //Convert list to a bitfield
          bitfield bf(len(_bf));
          for (int i = 0; i < len(_bf); ++i)
          {
              if (_bf[i])
                  bf.set_bit(i);
              else
                  bf.clear_bit(i);
          }
          if (override f = this->get_override("on_bitfield"))
              return f(bf);
          else
              return peer_plugin::on_bitfield(bf);
      }

      bool default_on_bitfield(const bitfield &bf)
      {
          return this->peer_plugin::on_bitfield(bf);
      }

      bool on_request(peer_request const& req)
      {
          if (override f = this->get_override("on_request"))
              return f(req);
          else
              return peer_plugin::on_request(req);
      }

      bool default_on_request(peer_request const& req)
      {
          return this->peer_plugin::on_request(req);
      }

      bool on_piece(peer_request const& piece, disk_buffer_holder& data)
      {
          if (override f = this->get_override("on_piece"))
              return f(piece, data);
          else
              return peer_plugin::on_piece(piece, data);
      }

      bool default_on_piece(peer_request const& piece, disk_buffer_holder& data)
      {
          return this->peer_plugin::on_piece(piece, data);
      }

      bool on_cancel(peer_request const& req)
      {
          if (override f = this->get_override("on_cancel"))
              return f(req);
          else
              return peer_plugin::on_cancel(req);
      }

      bool default_on_cancel(peer_request const& req)
      {
          return this->peer_plugin::on_cancel(req);
      }

      bool on_extended(int length, int msg, buffer::const_interval body)
      {
          if (override f = this->get_override("on_extended"))
              return f(length, msg, body);
          else
              return peer_plugin::on_extended(length, msg, body);
      }

      bool default_on_extended(int length, int msg, buffer::const_interval body)
      {
          return this->peer_plugin::on_extended(length, msg, body);
      }

      bool on_unknown_message(int length, int msg, buffer::const_interval body)
      {
          if (override f = this->get_override("on_unknown_message"))
              return f(length, msg, body);
          else
              return peer_plugin::on_unknown_message(length, msg, body);
      }

      bool default_on_unknown_message(int length, int msg, buffer::const_interval body)
      {
          return this->peer_plugin::on_unknown_message(length, msg, body);
      }

      void on_piece_pass(int index)
      {
          if (override f = this->get_override("on_piece_pass"))
              f(index);
          else
              peer_plugin::on_piece_pass(index);
      }

      void default_on_piece_pass(int index)
      {
          this->peer_plugin::on_piece_pass(index);
      }

      void on_piece_failed(int index)
      {
          if (override f = this->get_override("on_piece_failed"))
              f(index);
          else
              peer_plugin::on_piece_failed(index);
      }

      void default_on_piece_failed(int index)
      {
          this->peer_plugin::on_piece_failed(index);
      }

      void tick()
      {
          if (override f = this->get_override("tick"))
              f();
          else
              peer_plugin::tick();
      }

      void default_tick()
      {
          this->peer_plugin::tick();
      }

      bool write_request(peer_request const& req)
      {
          if (override f = this->get_override("write_request"))
              return f(req);
          else
              return peer_plugin::write_request(req);
      }

      bool default_write_request(peer_request const& req)
      {
          return this->peer_plugin::write_request(req);
      }
  };

  object get_buffer()
  {
      static char const data[] = "foobar";
      return object(handle<>(PyBuffer_FromMemory((void*)data, 6)));
  }

} // namespace unnamed

void bind_peer_plugin()
{
    class_<
        peer_plugin_wrap, boost::shared_ptr<peer_plugin_wrap>, boost::noncopyable
    >("peer_plugin")
        .def(
            "add_handshake"
          , &peer_plugin::add_handshake, &peer_plugin_wrap::default_add_handshake
        )
        .def(
            "on_handshake"
          , &peer_plugin::on_handshake, &peer_plugin_wrap::default_on_handshake
        )
        .def(
            "on_extension_handshake"
          , &peer_plugin::on_extension_handshake
          , &peer_plugin_wrap::default_on_extension_handshake
        )
        .def(
            "on_choke"
          , &peer_plugin::on_choke, &peer_plugin_wrap::default_on_choke
        )
        .def(
            "on_unchoke"
          , &peer_plugin::on_unchoke, &peer_plugin_wrap::default_on_unchoke
        )
        .def(
            "on_interested"
          , &peer_plugin::on_interested, &peer_plugin_wrap::default_on_interested
        )
        .def(
            "on_not_interested"
          , &peer_plugin::on_not_interested, &peer_plugin_wrap::default_on_not_interested
        )
        .def(
            "on_have"
          , &peer_plugin::on_have, &peer_plugin_wrap::default_on_have
        )
        .def(
            "on_bitfield"
          , &peer_plugin::on_bitfield, &peer_plugin_wrap::default_on_bitfield
        )
        .def(
            "on_request"
          , &peer_plugin::on_request, &peer_plugin_wrap::default_on_request
        )
        .def(
            "on_piece"
          , &peer_plugin::on_piece, &peer_plugin_wrap::default_on_piece
        )
        .def(
            "on_cancel"
          , &peer_plugin::on_cancel, &peer_plugin_wrap::default_on_cancel
        )
        .def(
            "on_piece_pass"
          , &peer_plugin::on_piece_pass, &peer_plugin_wrap::default_on_piece_pass
        )
        .def(
            "on_piece_failed"
          , &peer_plugin::on_piece_failed, &peer_plugin_wrap::default_on_piece_failed
        )
        .def(
            "tick"
          , &peer_plugin::tick, &peer_plugin_wrap::default_tick
        )
        .def(
            "write_request"
          , &peer_plugin::write_request, &peer_plugin_wrap::default_write_request
        )
        // These seem to make VC7.1 freeze. Needs special handling.

        /*.def(
            "on_extended"
          , &peer_plugin::on_extended, &peer_plugin_wrap::default_on_extended
        )
        .def(
            "on_unknown_message"
          , &peer_plugin::on_unknown_message, &peer_plugin_wrap::default_on_unknown_message
        )*/
        ;

    def("get_buffer", &get_buffer);
}

<commit_msg>fix build for FreeBSD<commit_after>// Copyright Daniel Wallin 2007. 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)

#include <cctype>
#include <iostream>

#include <libtorrent/extensions.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/lazy_entry.hpp>
#include <libtorrent/peer_request.hpp>
#include <libtorrent/disk_buffer_holder.hpp>
#include <libtorrent/bitfield.hpp>
#include <boost/python.hpp>

using namespace boost::python;
using namespace libtorrent;

namespace
{
  struct peer_plugin_wrap : peer_plugin, wrapper<peer_plugin>
  {
      void add_handshake(entry& e)
      {
          if (override f = this->get_override("add_handshake"))
              e = call<entry>(f.ptr(), e);
          else
              peer_plugin::add_handshake(e);
      }

      void default_add_handshake(entry& e)
      {
          this->peer_plugin::add_handshake(e);
      }

      bool on_handshake(char const* reserved_bits)
      {
          if (override f = this->get_override("on_handshake"))
              return f();
          else
              return peer_plugin::on_handshake(reserved_bits);
      }

      bool default_on_handshake(char const* reserved_bits)
      {
          return this->peer_plugin::on_handshake(reserved_bits);
      }

      bool on_extension_handshake(lazy_entry const& e)
      {
          if (override f = this->get_override("on_extension_handshake"))
              return f(e);
          else
              return peer_plugin::on_extension_handshake(e);
      }

      bool default_on_extension_handshake(lazy_entry const& e)
      {
          return this->peer_plugin::on_extension_handshake(e);
      }

      bool on_choke()
      {
          if (override f = this->get_override("on_choke"))
              return f();
          else
              return peer_plugin::on_choke();
      }

      bool default_on_choke()
      {
          return this->peer_plugin::on_choke();
      }

      bool on_unchoke()
      {
          if (override f = this->get_override("on_unchoke"))
              return f();
          else
              return peer_plugin::on_unchoke();
      }

      bool default_on_unchoke()
      {
          return this->peer_plugin::on_unchoke();
      }

      bool on_interested()
      {
          if (override f = this->get_override("on_interested"))
              return f();
          else
              return peer_plugin::on_interested();
      }

      bool default_on_interested()
      {
          return this->peer_plugin::on_interested();
      }

      bool on_not_interested()
      {
          if (override f = this->get_override("on_not_interested"))
              return f();
          else
              return peer_plugin::on_not_interested();
      }

      bool default_on_not_interested()
      {
          return this->peer_plugin::on_not_interested();
      }

      bool on_have(int index)
      {
          if (override f = this->get_override("on_have"))
              return f(index);
          else
              return peer_plugin::on_have(index);
      }

      bool default_on_have(int index)
      {
          return this->peer_plugin::on_have(index);
      }

      bool on_bitfield(list _bf)
      {
          //Convert list to a bitfield
          bitfield bf(len(_bf));
          for (int i = 0; i < len(_bf); ++i)
          {
              if (_bf[i])
                  bf.set_bit(i);
              else
                  bf.clear_bit(i);
          }
          if (override f = this->get_override("on_bitfield"))
              return f(bf);
          else
              return peer_plugin::on_bitfield(bf);
      }

      bool default_on_bitfield(const bitfield &bf)
      {
          return this->peer_plugin::on_bitfield(bf);
      }

      bool on_request(peer_request const& req)
      {
          if (override f = this->get_override("on_request"))
              return f(req);
          else
              return peer_plugin::on_request(req);
      }

      bool default_on_request(peer_request const& req)
      {
          return this->peer_plugin::on_request(req);
      }

      bool on_piece(peer_request const& piece, disk_buffer_holder& data)
      {
          if (override f = this->get_override("on_piece"))
              return f(piece, data);
          else
              return peer_plugin::on_piece(piece, data);
      }

      bool default_on_piece(peer_request const& piece, disk_buffer_holder& data)
      {
          return this->peer_plugin::on_piece(piece, data);
      }

      bool on_cancel(peer_request const& req)
      {
          if (override f = this->get_override("on_cancel"))
              return f(req);
          else
              return peer_plugin::on_cancel(req);
      }

      bool default_on_cancel(peer_request const& req)
      {
          return this->peer_plugin::on_cancel(req);
      }

      bool on_extended(int length, int msg, buffer::const_interval body)
      {
          if (override f = this->get_override("on_extended"))
              return f(length, msg, body);
          else
              return peer_plugin::on_extended(length, msg, body);
      }

      bool default_on_extended(int length, int msg, buffer::const_interval body)
      {
          return this->peer_plugin::on_extended(length, msg, body);
      }

      bool on_unknown_message(int length, int msg, buffer::const_interval body)
      {
          if (override f = this->get_override("on_unknown_message"))
              return f(length, msg, body);
          else
              return peer_plugin::on_unknown_message(length, msg, body);
      }

      bool default_on_unknown_message(int length, int msg, buffer::const_interval body)
      {
          return this->peer_plugin::on_unknown_message(length, msg, body);
      }

      void on_piece_pass(int index)
      {
          if (override f = this->get_override("on_piece_pass"))
              f(index);
          else
              peer_plugin::on_piece_pass(index);
      }

      void default_on_piece_pass(int index)
      {
          this->peer_plugin::on_piece_pass(index);
      }

      void on_piece_failed(int index)
      {
          if (override f = this->get_override("on_piece_failed"))
              f(index);
          else
              peer_plugin::on_piece_failed(index);
      }

      void default_on_piece_failed(int index)
      {
          this->peer_plugin::on_piece_failed(index);
      }

      void tick()
      {
          if (override f = this->get_override("tick"))
              f();
          else
              peer_plugin::tick();
      }

      void default_tick()
      {
          this->peer_plugin::tick();
      }

      bool write_request(peer_request const& req)
      {
          if (override f = this->get_override("write_request"))
              return f(req);
          else
              return peer_plugin::write_request(req);
      }

      bool default_write_request(peer_request const& req)
      {
          return this->peer_plugin::write_request(req);
      }
  };

  object get_buffer()
  {
      static char const data[] = "foobar";
      return object(handle<>(PyBuffer_FromMemory((void*)data, 6)));
  }

} // namespace unnamed

void bind_peer_plugin()
{
    class_<
        peer_plugin_wrap, boost::shared_ptr<peer_plugin_wrap>, boost::noncopyable
    >("peer_plugin")
        .def(
            "add_handshake"
          , &peer_plugin::add_handshake, &peer_plugin_wrap::default_add_handshake
        )
        .def(
            "on_handshake"
          , &peer_plugin::on_handshake, &peer_plugin_wrap::default_on_handshake
        )
        .def(
            "on_extension_handshake"
          , &peer_plugin::on_extension_handshake
          , &peer_plugin_wrap::default_on_extension_handshake
        )
        .def(
            "on_choke"
          , &peer_plugin::on_choke, &peer_plugin_wrap::default_on_choke
        )
        .def(
            "on_unchoke"
          , &peer_plugin::on_unchoke, &peer_plugin_wrap::default_on_unchoke
        )
        .def(
            "on_interested"
          , &peer_plugin::on_interested, &peer_plugin_wrap::default_on_interested
        )
        .def(
            "on_not_interested"
          , &peer_plugin::on_not_interested, &peer_plugin_wrap::default_on_not_interested
        )
        .def(
            "on_have"
          , &peer_plugin::on_have, &peer_plugin_wrap::default_on_have
        )
        .def(
            "on_bitfield"
          , &peer_plugin::on_bitfield, &peer_plugin_wrap::default_on_bitfield
        )
        .def(
            "on_request"
          , &peer_plugin::on_request, &peer_plugin_wrap::default_on_request
        )
        .def(
            "on_piece"
          , &peer_plugin::on_piece, &peer_plugin_wrap::default_on_piece
        )
        .def(
            "on_cancel"
          , &peer_plugin::on_cancel, &peer_plugin_wrap::default_on_cancel
        )
        .def(
            "on_piece_pass"
          , &peer_plugin::on_piece_pass, &peer_plugin_wrap::default_on_piece_pass
        )
        .def(
            "on_piece_failed"
          , &peer_plugin::on_piece_failed, &peer_plugin_wrap::default_on_piece_failed
        )
        .def(
            "tick"
          , &peer_plugin::tick, &peer_plugin_wrap::default_tick
        )
        .def(
            "write_request"
          , &peer_plugin::write_request, &peer_plugin_wrap::default_write_request
        )
        // These seem to make VC7.1 freeze. Needs special handling.

        /*.def(
            "on_extended"
          , &peer_plugin::on_extended, &peer_plugin_wrap::default_on_extended
        )
        .def(
            "on_unknown_message"
          , &peer_plugin::on_unknown_message, &peer_plugin_wrap::default_on_unknown_message
        )*/
        ;

    def("get_buffer", &get_buffer);
}

<|endoftext|>