<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <iostream>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#define I2C_ADDR (0x3C >> 1)

int file_i2c;
int length;
unsigned int microseconds;
unsigned char buffer[60] = {0};

void openi2c();
void compassInit();
void readCompass(int&, int&, int&);
int I2CRead(unsigned char, unsigned char&);
int I2CWrite(unsigned char, unsigned char);

int main()
{
    int x, y, z;
    openi2c();
    compassInit();
    while(1)
    {
      readCompass(x, y, z);
      std::cout << "x: " << x/2048.0*360 << " y: " << y/2048.0*360 << " z: " << z/2048.0*360 << std::endl ;
      usleep(1000000);
    }
    close(file_i2c);
    return 0;
}
void openi2c() {
  char *filename = (char*)"/dev/i2c-1";
	if ((file_i2c = open(filename, O_RDWR)) < 0)
	{
		//ERROR HANDLING: you can check errno to see what went wrong
		printf("Failed to open the i2c bus");
		return;
	}
}
void compassInit()
{
  I2CWrite(0x00, 0x90);
  I2CWrite(0x02, 0x00);
  usleep(100000);
}

void readCompass(int& x, int& y, int& z)
{
  unsigned char value[6];
  I2CRead(0x03, value[0]);
  I2CRead(0x04, value[1]);
  I2CRead(0x05, value[2]);
  I2CRead(0x06, value[3]);
  I2CRead(0x07, value[4]);
  I2CRead(0x08, value[5]);
  /*buffer[0] = 0x03;
  length = 1;
  if (write(file_i2c, buffer, length) != length)		//write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
  {
  		// ERROR HANDLING: i2c transaction failed
  		printf("3) Failed to write to the i2c bus.\n");
  }
  for(int i = 0; i < 6; i++)
  {
    usleep(1000);
    length = 1;			//<<< Number of bytes to read
    if (read(file_i2c, buffer, length) != length)		//read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
    {
      //ERROR HANDLING: i2c transaction failed
      printf("Failed to read from the i2c bus.\n");
    }
    else
    {
      printf("Data read: %x\n", buffer[0]);
      value[i] = buffer[0];
    }
  }*/
  x = (value[0] << 8) | value[1];
  z = (value[2] << 8) | value[3];
  y = (value[4] << 8) | value[5];
}

int I2CRead(unsigned char registerAddress, unsigned char &data) {
  unsigned char *inbuff, outbuff;
  int retVal = -1;
  struct i2c_rdwr_ioctl_data packets;
  struct i2c_msg messages[2];

  outbuff = registerAddress;
  messages[0].addr = I2C_ADDR;
  messages[0].flags= 0;
  messages[0].len = sizeof(outbuff);
  messages[0].buf = &outbuff;

  inbuff = &data;
  messages[1].addr = I2C_ADDR;
  messages[1].flags = I2C_M_RD;
  messages[1].len = sizeof(*inbuff);
  messages[1].buf = inbuff;

  packets.msgs = messages;
  packets.nmsgs = 2;

  retVal = ioctl(file_i2c, I2C_RDWR, &packets);
  if(retVal < 0)
      perror("Read from I2C Device failed");

  return retVal;
}

int I2CWrite(unsigned char registerAddress, unsigned char data) {
  unsigned char buff[2];
   int retVal = -1;
   struct i2c_rdwr_ioctl_data packets;
   struct i2c_msg messages[1];

   buff[0] = registerAddress;
   buff[1] = data;

   messages[0].addr = I2C_ADDR;
   messages[0].flags = 0;
   messages[0].len = sizeof(buff);
   messages[0].buf = buff;

   packets.msgs = messages;
   packets.nmsgs = 1;

   retVal = ioctl(file_i2c, I2C_RDWR, &packets);
   if(retVal < 0)
       perror("Write to I2C Device failed");

   return retVal;
}
<commit_msg>COMPASS IS WORKINGgit status! (we might want to play with gain though)<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <iostream>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

#define I2C_ADDR (0x3C >> 1)

int file_i2c;
int length;
unsigned int microseconds;
unsigned char buffer[60] = {0};

void openi2c();
void compassInit();
void readCompass(short&, short&, short&);
int I2CRead(unsigned char, unsigned char&);
int I2CWrite(unsigned char, unsigned char);

int main()
{
    short x, y, z;
    openi2c();
    compassInit();
    while(1)
    {
      readCompass(x, y, z);
      std::cout << "x: " << x/2048.0*360 << " y: " << y/2048.0*360 << " z: " << z/2048.0*360 << std::endl ;
      usleep(1000000);
    }
    close(file_i2c);
    return 0;
}
void openi2c() {
  char *filename = (char*)"/dev/i2c-1";
	if ((file_i2c = open(filename, O_RDWR)) < 0)
	{
		//ERROR HANDLING: you can check errno to see what went wrong
		printf("Failed to open the i2c bus");
		return;
	}
}
void compassInit()
{
  I2CWrite(0x00, 0x90);
  I2CWrite(0x02, 0x00);
  usleep(100000);
}

void readCompass(short& x, short& y, short& z)
{
  unsigned char value[6];
  I2CRead(0x03, value[0]);
  I2CRead(0x04, value[1]);
  I2CRead(0x05, value[2]);
  I2CRead(0x06, value[3]);
  I2CRead(0x07, value[4]);
  I2CRead(0x08, value[5]);
  /*buffer[0] = 0x03;
  length = 1;
  if (write(file_i2c, buffer, length) != length)		//write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
  {
  		// ERROR HANDLING: i2c transaction failed
  		printf("3) Failed to write to the i2c bus.\n");
  }
  for(int i = 0; i < 6; i++)
  {
    usleep(1000);
    length = 1;			//<<< Number of bytes to read
    if (read(file_i2c, buffer, length) != length)		//read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
    {
      //ERROR HANDLING: i2c transaction failed
      printf("Failed to read from the i2c bus.\n");
    }
    else
    {
      printf("Data read: %x\n", buffer[0]);
      value[i] = buffer[0];
    }
  }*/
  x = (value[0] << 8) | value[1];
  z = (value[2] << 8) | value[3];
  y = (value[4] << 8) | value[5];
}

int I2CRead(unsigned char registerAddress, unsigned char &data) {
  unsigned char *inbuff, outbuff;
  int retVal = -1;
  struct i2c_rdwr_ioctl_data packets;
  struct i2c_msg messages[2];

  outbuff = registerAddress;
  messages[0].addr = I2C_ADDR;
  messages[0].flags= 0;
  messages[0].len = sizeof(outbuff);
  messages[0].buf = &outbuff;

  inbuff = &data;
  messages[1].addr = I2C_ADDR;
  messages[1].flags = I2C_M_RD;
  messages[1].len = sizeof(*inbuff);
  messages[1].buf = inbuff;

  packets.msgs = messages;
  packets.nmsgs = 2;

  retVal = ioctl(file_i2c, I2C_RDWR, &packets);
  if(retVal < 0)
      perror("Read from I2C Device failed");

  return retVal;
}

int I2CWrite(unsigned char registerAddress, unsigned char data) {
  unsigned char buff[2];
   int retVal = -1;
   struct i2c_rdwr_ioctl_data packets;
   struct i2c_msg messages[1];

   buff[0] = registerAddress;
   buff[1] = data;

   messages[0].addr = I2C_ADDR;
   messages[0].flags = 0;
   messages[0].len = sizeof(buff);
   messages[0].buf = buff;

   packets.msgs = messages;
   packets.nmsgs = 1;

   retVal = ioctl(file_i2c, I2C_RDWR, &packets);
   if(retVal < 0)
       perror("Write to I2C Device failed");

   return retVal;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <ncurses.h>

#define I2C_ADDR 0x1E

int handle;
unsigned char command[2];

void compassInit();
void readCompass(int&, int&, int&);

void compassInit()
{
  handle = i2cOpen(1, I2C_ADDR, 0);
  command[0] = 0x00;
  command[1] = 0xB8;
  i2cWriteDevice(handle, command&, 2);
}

void readCompass(int x&, int y&, int z&)
{
  unsigned char value[6];
  const int firstByte = 0x03;
  for(i = 0; i < 6; i++)
  {
    value[i] = i2cReadByteData(handle, firstByte+i);
  }
  x = (value[0] << 8) | value[1];
  z = (value[2] << 8) | value[3];
  y = (value[4] << 8) | value[5];
}
<commit_msg>got compass to compilesudo ./compass !<commit_after>#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <iostream>
#include <linux/i2c-dev.h>

#define I2C_ADDR 0x1E

int file_i2c;
int length;
unsigned char buffer[60] = {0};

void compassInit();
void readCompass(int&, int&, int&);

int main()
{
    int x, y, z;
    compassInit();
    /*readCompass(x, y, z);
    std::cout << "x: " << x << " y: " << y << " z: " << z << std::endl ;
*/}

void compassInit()
{
  char *filename = (char*)"/dev/i2c-1";
	if ((file_i2c = open(filename, O_RDWR)) < 0)
	{
		//ERROR HANDLING: you can check errno to see what went wrong
		printf("Failed to open the i2c bus");
		return;
	}
  if (ioctl(file_i2c, I2C_SLAVE, I2C_ADDR) < 0)
  {
    printf("Failed to acquire bus access and/or talk to slave.\n");
    //ERROR HANDLING; you can check errno to see what went wrong
    return;
  }
  buffer[0] = 0x00;
  buffer[1] = 0xB8;
  length = 2;			//<<< Number of bytes to write
  if (write(file_i2c, buffer, length) != length)		//write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
  {
  		/* ERROR HANDLING: i2c transaction failed */
  		printf("Failed to write to the i2c bus.\n");
  }
  buffer[0] = 0x02;
  buffer[1] = 0x00;
  length = 2;			//<<< Number of bytes to write
  if (write(file_i2c, buffer, length) != length)		//write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
  {
  		/* ERROR HANDLING: i2c transaction failed */
  		printf("Failed to write to the i2c bus.\n");
  }
}

void readCompass(int& x, int& y, int& z)
{
  unsigned char value[6];
  buffer[0] = 0x03;
  length = 1;
  if (write(file_i2c, buffer, length) != length)		//write() returns the number of bytes actually written, if it doesn't match then an error occurred (e.g. no response from the device)
  {
  		/* ERROR HANDLING: i2c transaction failed */
  		printf("Failed to write to the i2c bus.\n");
  }
  for(int i = 0; i < 6; i++)
  {
    length = 1;			//<<< Number of bytes to read
    if (read(file_i2c, buffer, length) != length)		//read() returns the number of bytes actually read, if it doesn't match then an error occurred (e.g. no response from the device)
    {
      //ERROR HANDLING: i2c transaction failed
      printf("Failed to read from the i2c bus.\n");
    }
    else
    {
      printf("Data read: %s\n", buffer);
      value[i] = buffer[0];
    }
  }
  x = (value[0] << 8) | value[1];
  z = (value[2] << 8) | value[3];
  y = (value[4] << 8) | value[5];
}
<|endoftext|>


<commit_before>#pragma once

#include <functional>
#include <memory>
#include <string>
#include <sdbusplus/slot.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/message.hpp>

namespace sdbusplus
{

namespace bus
{

namespace match
{

struct match
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *         - Copy operations due to internal unique_ptr.
     *     Allowed:
     *         - Move operations.
     *         - Destructor.
     */
    match() = delete;
    match(const match&) = delete;
    match& operator=(const match&) = delete;
    match(match&&) = default;
    match& operator=(match&&) = default;
    ~match() = default;

    /** @brief Register a signal match.
     *
     *  @param[in] bus - The bus to register on.
     *  @param[in] match - The match to register.
     *  @param[in] handler - The callback for matches.
     *  @param[in] context - An optional context to pass to the handler.
     */
    match(sdbusplus::bus::bus& bus, const char* match,
          sd_bus_message_handler_t handler, void* context = nullptr)
                : _slot(nullptr)
    {
        sd_bus_slot* slot = nullptr;
        sd_bus_add_match(bus.get(), &slot, match, handler, context);

        _slot = decltype(_slot){slot};
    }
    match(sdbusplus::bus::bus& bus, const std::string& _match,
          sd_bus_message_handler_t handler, void* context = nullptr)
                : match(bus, _match.c_str(), handler, context) {}

    using callback_t = std::function<void(sdbusplus::message::message&)>;

    /** @brief Register a signal match.
     *
     *  @param[in] bus - The bus to register on.
     *  @param[in] match - The match to register.
     *  @param[in] callback - The callback for matches.
     */
    match(sdbusplus::bus::bus& bus, const char* match,
          callback_t callback)
                : _slot(nullptr),
                  _callback(std::make_unique<callback_t>(std::move(callback)))
    {
        sd_bus_slot* slot = nullptr;
        sd_bus_add_match(bus.get(), &slot, match, callCallback,
                         _callback.get());

        _slot = decltype(_slot){slot};
    }
    match(sdbusplus::bus::bus& bus, const std::string& _match,
          callback_t callback)
                : match(bus, _match.c_str(), callback) {}

    private:
        slot::slot _slot;
        std::unique_ptr<callback_t> _callback = nullptr;

        static int callCallback(sd_bus_message *m, void* context,
                                sd_bus_error* e)
        {
            auto c = static_cast<callback_t*>(context);
            message::message message{m};

            (*c)(message);

            return 0;
        }
};

/** Utilities for defining match rules based on the DBus specification */
namespace rules
{

using namespace std::string_literals;

namespace type
{

inline auto signal() { return "type='signal',"s; }
inline auto method() { return "type='method',"s; }
inline auto method_return() { return "type='method_return',"s; }
inline auto error() { return "type='error',"s; }

} // namespace type

inline auto sender(const std::string& s) { return "sender='"s + s + "',"; }
inline auto interface(const std::string& s)
        { return "interface='"s + s + "',"; }
inline auto member(const std::string& s) { return "member='"s + s + "',"; }
inline auto path(const std::string& s) { return "path='"s + s + "',"; }
inline auto path_namespace(const std::string& s)
        { return "path_namespace='"s + s + "',"; }
inline auto destination(const std::string& s)
        { return "destination='"s + s + "',"; }
inline auto argN(size_t n, const std::string& s)
        { return "arg"s + std::to_string(n) + "='"s + s + "',"; }
inline auto argNpath(size_t n, const std::string& s)
        { return "arg"s + std::to_string(n) + "path='"s + s + "',"; }
inline auto arg0namespace(const std::string& s)
        { return "arg0namespace='"s + s + "',"; }
inline auto eavesdrop() { return "eavesdrop='true',"s; }

inline auto nameOwnerChanged()
{
    return "type='signal',"
           "sender='org.freedesktop.DBus',"
           "member='NameOwnerChanged',"s;
}

} // namespace rules
} // namespace match

using match_t = match::match;

} // namespace bus
} // namespace sdbusplus
<commit_msg>match: add interfacesAdded rule<commit_after>#pragma once

#include <functional>
#include <memory>
#include <string>
#include <sdbusplus/slot.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/message.hpp>

namespace sdbusplus
{

namespace bus
{

namespace match
{

struct match
{
    /* Define all of the basic class operations:
     *     Not allowed:
     *         - Default constructor to avoid nullptrs.
     *         - Copy operations due to internal unique_ptr.
     *     Allowed:
     *         - Move operations.
     *         - Destructor.
     */
    match() = delete;
    match(const match&) = delete;
    match& operator=(const match&) = delete;
    match(match&&) = default;
    match& operator=(match&&) = default;
    ~match() = default;

    /** @brief Register a signal match.
     *
     *  @param[in] bus - The bus to register on.
     *  @param[in] match - The match to register.
     *  @param[in] handler - The callback for matches.
     *  @param[in] context - An optional context to pass to the handler.
     */
    match(sdbusplus::bus::bus& bus, const char* match,
          sd_bus_message_handler_t handler, void* context = nullptr)
                : _slot(nullptr)
    {
        sd_bus_slot* slot = nullptr;
        sd_bus_add_match(bus.get(), &slot, match, handler, context);

        _slot = decltype(_slot){slot};
    }
    match(sdbusplus::bus::bus& bus, const std::string& _match,
          sd_bus_message_handler_t handler, void* context = nullptr)
                : match(bus, _match.c_str(), handler, context) {}

    using callback_t = std::function<void(sdbusplus::message::message&)>;

    /** @brief Register a signal match.
     *
     *  @param[in] bus - The bus to register on.
     *  @param[in] match - The match to register.
     *  @param[in] callback - The callback for matches.
     */
    match(sdbusplus::bus::bus& bus, const char* match,
          callback_t callback)
                : _slot(nullptr),
                  _callback(std::make_unique<callback_t>(std::move(callback)))
    {
        sd_bus_slot* slot = nullptr;
        sd_bus_add_match(bus.get(), &slot, match, callCallback,
                         _callback.get());

        _slot = decltype(_slot){slot};
    }
    match(sdbusplus::bus::bus& bus, const std::string& _match,
          callback_t callback)
                : match(bus, _match.c_str(), callback) {}

    private:
        slot::slot _slot;
        std::unique_ptr<callback_t> _callback = nullptr;

        static int callCallback(sd_bus_message *m, void* context,
                                sd_bus_error* e)
        {
            auto c = static_cast<callback_t*>(context);
            message::message message{m};

            (*c)(message);

            return 0;
        }
};

/** Utilities for defining match rules based on the DBus specification */
namespace rules
{

using namespace std::string_literals;

namespace type
{

inline auto signal() { return "type='signal',"s; }
inline auto method() { return "type='method',"s; }
inline auto method_return() { return "type='method_return',"s; }
inline auto error() { return "type='error',"s; }

} // namespace type

inline auto sender(const std::string& s) { return "sender='"s + s + "',"; }
inline auto interface(const std::string& s)
        { return "interface='"s + s + "',"; }
inline auto member(const std::string& s) { return "member='"s + s + "',"; }
inline auto path(const std::string& s) { return "path='"s + s + "',"; }
inline auto path_namespace(const std::string& s)
        { return "path_namespace='"s + s + "',"; }
inline auto destination(const std::string& s)
        { return "destination='"s + s + "',"; }
inline auto argN(size_t n, const std::string& s)
        { return "arg"s + std::to_string(n) + "='"s + s + "',"; }
inline auto argNpath(size_t n, const std::string& s)
        { return "arg"s + std::to_string(n) + "path='"s + s + "',"; }
inline auto arg0namespace(const std::string& s)
        { return "arg0namespace='"s + s + "',"; }
inline auto eavesdrop() { return "eavesdrop='true',"s; }

inline auto nameOwnerChanged()
{
    return "type='signal',"
           "sender='org.freedesktop.DBus',"
           "member='NameOwnerChanged',"s;
}

inline auto interfacesAdded()
{
    return "type='signal',"
           "interface='org.freedesktop.DBus.ObjectManager',"
           "member='InterfacesAdded',"s;
}

} // namespace rules
} // namespace match

using match_t = match::match;

} // namespace bus
} // namespace sdbusplus
<|endoftext|>


<commit_before>#pragma once

#include <cassert>
#include <functional>  // hash
#include <iosfwd>
#include <type_traits> // aligned_storage, alignment_of, result_of
#include <utility>     // forward

#include "sdd/util/typelist.hh"

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename T, typename... Types>
struct largest_alignment
{
  static constexpr std::size_t tail  = largest_alignment<Types...>::value;
  static constexpr std::size_t head  = std::alignment_of<T>::value;
  static constexpr std::size_t value = tail > head ? tail : head;
};

template <typename T>
struct largest_alignment<T>
{
  static constexpr std::size_t value = std::alignment_of<T>::value;
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename T, typename... Types>
struct largest_size
{
  static constexpr std::size_t tail  = largest_size<Types...>::value;
  static constexpr std::size_t head  = sizeof(T);
  static constexpr std::size_t value = tail > head ? tail : head;
};

template <typename T>
struct largest_size<T>
{
  static constexpr std::size_t value = sizeof(T);
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief A storage large enough for the biggest T in Types.
///
/// When the packed mode is required (at compilation time), we don't care about alignement to save
/// on memory.
template <std::size_t Len, typename... Types>
struct union_storage
{
  static constexpr std::size_t max_size = largest_size<Types...>::value;
#ifdef LIBSDD_PACKED
  static constexpr std::size_t alignment_value = 1;
#else
  static constexpr std::size_t alignment_value = largest_alignment<Types...>::value;
#endif
  using type = typename std::aligned_storage< (Len > max_size ? Len : max_size)
                                            , alignment_value
                                            >::type;
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Dispatch the destructor to the contained type in the visited variant.
struct dtor_visitor
{
  template <typename T>
  void
  operator()(const T& x)
  const noexcept(noexcept(x.~T()))
  {
    x.~T();
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
struct hash_visitor
{
  template <typename T>
  std::size_t
  operator()(const T& x)
  const noexcept(noexcept(std::hash<T>()(x)))
  {
    return std::hash<T>()(x);
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
struct eq_visitor
{
  template <typename T>
  bool
  operator()(const T& lhs, const T& rhs)
  const noexcept
  {
    static_assert(noexcept(lhs == rhs), "Comparison should be noexcept");
    return lhs == rhs;
  }

  template <typename T, typename U>
  bool
  operator()(const T&, const U&)
  const noexcept
  {
    assert(false);
    __builtin_unreachable();
  }
};

/*------------------------------------------------------------------------------------------------*/

template <typename... Types>
struct variant;

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename X, typename... Args>
inline
auto
call(Visitor&& v, const void* x, Args&&... args)
noexcept(noexcept(v(*static_cast<const X*>(x), std::forward<Args>(args)...)))
-> decltype(auto)
{
  return v(*static_cast<const X*>(x), std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename... Xs, typename... Args>
inline
std::result_of_t<Visitor(util::nth_t<0, Xs...>, Args&&...)>
apply_visitor(Visitor&& v, const variant<Xs...>& x, Args&&... args)
{
  using fun_ptr_type
    = std::result_of_t<Visitor(util::nth_t<0, Xs...>, Args&&...)>
      (*) (Visitor&&, const void*, Args&&...);

  static constexpr fun_ptr_type table[] = {&call<Visitor, Xs, Args&&...>...};

  return table[x.index](std::forward<Visitor>(v), &x.storage, std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename X, typename Y, typename... Args>
inline
auto
binary_call(Visitor&& v, const void* x, const void* y, Args&&... args)
-> decltype(auto)
{
  return v(*static_cast<const X*>(x), *static_cast<const Y*>(y), std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Expands a list of pairs of types into pointers to binary_call.
template<typename Visitor, typename T, std::size_t N, typename... Args>
struct binary_jump_table
{
    template<class... Xs, class... Ys>
    constexpr binary_jump_table(util::list<util::pair<Xs, Ys>...>)
      : table{&binary_call<Visitor, Xs, Ys, Args...>...}
    {}

    T table[N];
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename... Xs, typename... Ys, typename... Args>
std::result_of_t<Visitor(util::nth_t<0, Xs...>, util::nth_t<0, Ys...>, Args&&...)>
apply_binary_visitor(Visitor&& v, const variant<Xs...>& x, const variant<Ys...>& y, Args&&... args)
{
  using fun_ptr_type
    = std::result_of_t<Visitor(util::nth_t<0, Xs...>, util::nth_t<0, Ys...>, Args&&...)>
      (*) (Visitor&&, const void*, const void*, Args&&...);

  static constexpr binary_jump_table<Visitor, fun_ptr_type, sizeof...(Xs) * sizeof...(Ys), Args...>
    table = {typename util::join<util::list<Xs...>, util::list<Ys...>>::type()};

  return table.table[x.index * sizeof...(Ys) + y.index]
    (std::forward<Visitor>(v), &x.storage, &y.storage, std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem
<commit_msg>Give StackOverflow reference<commit_after>#pragma once

#include <cassert>
#include <functional>  // hash
#include <iosfwd>
#include <type_traits> // aligned_storage, alignment_of, result_of
#include <utility>     // forward

#include "sdd/util/typelist.hh"

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename T, typename... Types>
struct largest_alignment
{
  static constexpr std::size_t tail  = largest_alignment<Types...>::value;
  static constexpr std::size_t head  = std::alignment_of<T>::value;
  static constexpr std::size_t value = tail > head ? tail : head;
};

template <typename T>
struct largest_alignment<T>
{
  static constexpr std::size_t value = std::alignment_of<T>::value;
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename T, typename... Types>
struct largest_size
{
  static constexpr std::size_t tail  = largest_size<Types...>::value;
  static constexpr std::size_t head  = sizeof(T);
  static constexpr std::size_t value = tail > head ? tail : head;
};

template <typename T>
struct largest_size<T>
{
  static constexpr std::size_t value = sizeof(T);
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief A storage large enough for the biggest T in Types.
///
/// When the packed mode is required (at compilation time), we don't care about alignement to save
/// on memory.
template <std::size_t Len, typename... Types>
struct union_storage
{
  static constexpr std::size_t max_size = largest_size<Types...>::value;
#ifdef LIBSDD_PACKED
  static constexpr std::size_t alignment_value = 1;
#else
  static constexpr std::size_t alignment_value = largest_alignment<Types...>::value;
#endif
  using type = typename std::aligned_storage< (Len > max_size ? Len : max_size)
                                            , alignment_value
                                            >::type;
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Dispatch the destructor to the contained type in the visited variant.
struct dtor_visitor
{
  template <typename T>
  void
  operator()(const T& x)
  const noexcept(noexcept(x.~T()))
  {
    x.~T();
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
struct hash_visitor
{
  template <typename T>
  std::size_t
  operator()(const T& x)
  const noexcept(noexcept(std::hash<T>()(x)))
  {
    return std::hash<T>()(x);
  }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
struct eq_visitor
{
  template <typename T>
  bool
  operator()(const T& lhs, const T& rhs)
  const noexcept
  {
    static_assert(noexcept(lhs == rhs), "Comparison should be noexcept");
    return lhs == rhs;
  }

  template <typename T, typename U>
  bool
  operator()(const T&, const U&)
  const noexcept
  {
    assert(false);
    __builtin_unreachable();
  }
};

/*------------------------------------------------------------------------------------------------*/

template <typename... Types>
struct variant;

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename X, typename... Args>
inline
auto
call(Visitor&& v, const void* x, Args&&... args)
noexcept(noexcept(v(*static_cast<const X*>(x), std::forward<Args>(args)...)))
-> decltype(auto)
{
  return v(*static_cast<const X*>(x), std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename... Xs, typename... Args>
inline
std::result_of_t<Visitor(util::nth_t<0, Xs...>, Args&&...)>
apply_visitor(Visitor&& v, const variant<Xs...>& x, Args&&... args)
{
  using fun_ptr_type
    = std::result_of_t<Visitor(util::nth_t<0, Xs...>, Args&&...)>
      (*) (Visitor&&, const void*, Args&&...);

  static constexpr fun_ptr_type table[] = {&call<Visitor, Xs, Args&&...>...};

  return table[x.index](std::forward<Visitor>(v), &x.storage, std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename X, typename Y, typename... Args>
inline
auto
binary_call(Visitor&& v, const void* x, const void* y, Args&&... args)
-> decltype(auto)
{
  return v(*static_cast<const X*>(x), *static_cast<const Y*>(y), std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Expands a list of pairs of types into pointers to binary_call.
/// @see http://stackoverflow.com/a/25661431/21584
template<typename Visitor, typename T, std::size_t N, typename... Args>
struct binary_jump_table
{
    template<class... Xs, class... Ys>
    constexpr binary_jump_table(util::list<util::pair<Xs, Ys>...>)
      : table{&binary_call<Visitor, Xs, Ys, Args...>...}
    {}

    T table[N];
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
template <typename Visitor, typename... Xs, typename... Ys, typename... Args>
std::result_of_t<Visitor(util::nth_t<0, Xs...>, util::nth_t<0, Ys...>, Args&&...)>
apply_binary_visitor(Visitor&& v, const variant<Xs...>& x, const variant<Ys...>& y, Args&&... args)
{
  using fun_ptr_type
    = std::result_of_t<Visitor(util::nth_t<0, Xs...>, util::nth_t<0, Ys...>, Args&&...)>
      (*) (Visitor&&, const void*, const void*, Args&&...);

  static constexpr binary_jump_table<Visitor, fun_ptr_type, sizeof...(Xs) * sizeof...(Ys), Args...>
    table = {typename util::join<util::list<Xs...>, util::list<Ys...>>::type()};

  return table.table[x.index * sizeof...(Ys) + y.index]
    (std::forward<Visitor>(v), &x.storage, &y.storage, std::forward<Args>(args)...);
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem
<|endoftext|>


<commit_before>#include "selfdrive/ui/qt/home.h"

#include <QDateTime>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QVBoxLayout>

#include "selfdrive/common/params.h"
#include "selfdrive/common/swaglog.h"
#include "selfdrive/common/timing.h"
#include "selfdrive/common/util.h"
#include "selfdrive/ui/qt/widgets/drive_stats.h"
#include "selfdrive/ui/qt/widgets/setup.h"

// HomeWindow: the container for the offroad and onroad UIs

HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
  QHBoxLayout *layout = new QHBoxLayout(this);
  layout->setMargin(0);
  layout->setSpacing(0);

  sidebar = new Sidebar(this);
  layout->addWidget(sidebar);
  QObject::connect(this, &HomeWindow::update, sidebar, &Sidebar::updateState);
  QObject::connect(sidebar, &Sidebar::openSettings, this, &HomeWindow::openSettings);

  slayout = new QStackedLayout();
  layout->addLayout(slayout);

  onroad = new OnroadWindow(this);
  slayout->addWidget(onroad);

  QObject::connect(this, &HomeWindow::update, onroad, &OnroadWindow::update);
  QObject::connect(this, &HomeWindow::offroadTransitionSignal, onroad, &OnroadWindow::offroadTransitionSignal);

  home = new OffroadHome();
  slayout->addWidget(home);
  QObject::connect(this, &HomeWindow::openSettings, home, &OffroadHome::refresh);

  driver_view = new DriverViewWindow(this);
  connect(driver_view, &DriverViewWindow::done, [=] {
    showDriverView(false);
  });
  slayout->addWidget(driver_view);

  setLayout(layout);
}

void HomeWindow::offroadTransition(bool offroad) {
  if (offroad) {
    slayout->setCurrentWidget(home);
  } else {
    slayout->setCurrentWidget(onroad);
  }
  sidebar->setVisible(offroad);
  emit offroadTransitionSignal(offroad);
}

void HomeWindow::showDriverView(bool show) {
  if (show) {
    emit closeSettings();
    slayout->setCurrentWidget(driver_view);
  } else {
    slayout->setCurrentWidget(home);
  }
  sidebar->setVisible(show == false);
}

void HomeWindow::mousePressEvent(QMouseEvent* e) {
  // Handle sidebar collapsing
  if (onroad->isVisible() && (!sidebar->isVisible() || e->x() > sidebar->width())) {

    // TODO: Handle this without exposing pointer to map widget
    // Hide map first if visible, then hide sidebar
    if (onroad->map != nullptr && onroad->map->isVisible()) {
      onroad->map->setVisible(false);
    } else if (!sidebar->isVisible()) {
      sidebar->setVisible(true);
    } else {
      sidebar->setVisible(false);

      if (onroad->map != nullptr) onroad->map->setVisible(true);
    }
  }
}

// OffroadHome: the offroad home page

OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
  QVBoxLayout* main_layout = new QVBoxLayout();
  main_layout->setMargin(50);

  // top header
  QHBoxLayout* header_layout = new QHBoxLayout();

  date = new QLabel();
  date->setStyleSheet(R"(font-size: 55px;)");
  header_layout->addWidget(date, 0, Qt::AlignHCenter | Qt::AlignLeft);

  alert_notification = new QPushButton();
  alert_notification->setVisible(false);
  QObject::connect(alert_notification, &QPushButton::released, this, &OffroadHome::openAlerts);
  header_layout->addWidget(alert_notification, 0, Qt::AlignHCenter | Qt::AlignRight);

  std::string brand = Params().getBool("Passive") ? "dashcam" : "openpilot";
  QLabel* version = new QLabel(QString::fromStdString(brand + " v" + Params().get("Version")));
  version->setStyleSheet(R"(font-size: 55px;)");
  header_layout->addWidget(version, 0, Qt::AlignHCenter | Qt::AlignRight);

  main_layout->addLayout(header_layout);

  // main content
  main_layout->addSpacing(25);
  center_layout = new QStackedLayout();

  QHBoxLayout* statsAndSetup = new QHBoxLayout();
  statsAndSetup->setMargin(0);

  DriveStats* drive = new DriveStats;
  drive->setFixedSize(800, 800);
  statsAndSetup->addWidget(drive);

  SetupWidget* setup = new SetupWidget;
  statsAndSetup->addWidget(setup);

  QWidget* statsAndSetupWidget = new QWidget();
  statsAndSetupWidget->setLayout(statsAndSetup);

  center_layout->addWidget(statsAndSetupWidget);

  alerts_widget = new OffroadAlert();
  QObject::connect(alerts_widget, &OffroadAlert::closeAlerts, this, &OffroadHome::closeAlerts);
  center_layout->addWidget(alerts_widget);
  center_layout->setAlignment(alerts_widget, Qt::AlignCenter);

  main_layout->addLayout(center_layout, 1);

  // set up refresh timer
  timer = new QTimer(this);
  QObject::connect(timer, &QTimer::timeout, this, &OffroadHome::refresh);
  timer->start(10 * 1000);

  setLayout(main_layout);
  setStyleSheet(R"(
    OffroadHome {
      background-color: black;
    }
    * {
     color: white;
    }
  )");
}

void OffroadHome::showEvent(QShowEvent *event) {
  refresh();
}

void OffroadHome::openAlerts() {
  center_layout->setCurrentIndex(1);
}

void OffroadHome::closeAlerts() {
  center_layout->setCurrentIndex(0);
}

void OffroadHome::refresh() {
  bool first_refresh = !date->text().size();
  if (!isVisible() && !first_refresh) {
    return;
  }

  date->setText(QDateTime::currentDateTime().toString("dddd, MMMM d"));

  // update alerts

  alerts_widget->refresh();
  if (!alerts_widget->alertCount && !alerts_widget->updateAvailable) {
    closeAlerts();
    alert_notification->setVisible(false);
    return;
  }

  if (alerts_widget->updateAvailable) {
    alert_notification->setText("UPDATE");
  } else {
    int alerts = alerts_widget->alertCount;
    alert_notification->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S"));
  }

  if (!alert_notification->isVisible() && !first_refresh) {
    emit openAlerts();
  }
  alert_notification->setVisible(true);

  // Red background for alerts, blue for update available
  QString style = QString(R"(
    padding: 15px;
    padding-left: 30px;
    padding-right: 30px;
    border: 1px solid;
    border-radius: 5px;
    font-size: 40px;
    font-weight: 500;
    background-color: #E22C2C;
  )");
  if (alerts_widget->updateAvailable) {
    style.replace("#E22C2C", "#364DEF");
  }
  alert_notification->setStyleSheet(style);
}
<commit_msg>OffroadHome::refresh(): remove emit keyword on slot (#21227)<commit_after>#include "selfdrive/ui/qt/home.h"

#include <QDateTime>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QVBoxLayout>

#include "selfdrive/common/params.h"
#include "selfdrive/common/swaglog.h"
#include "selfdrive/common/timing.h"
#include "selfdrive/common/util.h"
#include "selfdrive/ui/qt/widgets/drive_stats.h"
#include "selfdrive/ui/qt/widgets/setup.h"

// HomeWindow: the container for the offroad and onroad UIs

HomeWindow::HomeWindow(QWidget* parent) : QWidget(parent) {
  QHBoxLayout *layout = new QHBoxLayout(this);
  layout->setMargin(0);
  layout->setSpacing(0);

  sidebar = new Sidebar(this);
  layout->addWidget(sidebar);
  QObject::connect(this, &HomeWindow::update, sidebar, &Sidebar::updateState);
  QObject::connect(sidebar, &Sidebar::openSettings, this, &HomeWindow::openSettings);

  slayout = new QStackedLayout();
  layout->addLayout(slayout);

  onroad = new OnroadWindow(this);
  slayout->addWidget(onroad);

  QObject::connect(this, &HomeWindow::update, onroad, &OnroadWindow::update);
  QObject::connect(this, &HomeWindow::offroadTransitionSignal, onroad, &OnroadWindow::offroadTransitionSignal);

  home = new OffroadHome();
  slayout->addWidget(home);
  QObject::connect(this, &HomeWindow::openSettings, home, &OffroadHome::refresh);

  driver_view = new DriverViewWindow(this);
  connect(driver_view, &DriverViewWindow::done, [=] {
    showDriverView(false);
  });
  slayout->addWidget(driver_view);

  setLayout(layout);
}

void HomeWindow::offroadTransition(bool offroad) {
  if (offroad) {
    slayout->setCurrentWidget(home);
  } else {
    slayout->setCurrentWidget(onroad);
  }
  sidebar->setVisible(offroad);
  emit offroadTransitionSignal(offroad);
}

void HomeWindow::showDriverView(bool show) {
  if (show) {
    emit closeSettings();
    slayout->setCurrentWidget(driver_view);
  } else {
    slayout->setCurrentWidget(home);
  }
  sidebar->setVisible(show == false);
}

void HomeWindow::mousePressEvent(QMouseEvent* e) {
  // Handle sidebar collapsing
  if (onroad->isVisible() && (!sidebar->isVisible() || e->x() > sidebar->width())) {

    // TODO: Handle this without exposing pointer to map widget
    // Hide map first if visible, then hide sidebar
    if (onroad->map != nullptr && onroad->map->isVisible()) {
      onroad->map->setVisible(false);
    } else if (!sidebar->isVisible()) {
      sidebar->setVisible(true);
    } else {
      sidebar->setVisible(false);

      if (onroad->map != nullptr) onroad->map->setVisible(true);
    }
  }
}

// OffroadHome: the offroad home page

OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
  QVBoxLayout* main_layout = new QVBoxLayout();
  main_layout->setMargin(50);

  // top header
  QHBoxLayout* header_layout = new QHBoxLayout();

  date = new QLabel();
  date->setStyleSheet(R"(font-size: 55px;)");
  header_layout->addWidget(date, 0, Qt::AlignHCenter | Qt::AlignLeft);

  alert_notification = new QPushButton();
  alert_notification->setVisible(false);
  QObject::connect(alert_notification, &QPushButton::released, this, &OffroadHome::openAlerts);
  header_layout->addWidget(alert_notification, 0, Qt::AlignHCenter | Qt::AlignRight);

  std::string brand = Params().getBool("Passive") ? "dashcam" : "openpilot";
  QLabel* version = new QLabel(QString::fromStdString(brand + " v" + Params().get("Version")));
  version->setStyleSheet(R"(font-size: 55px;)");
  header_layout->addWidget(version, 0, Qt::AlignHCenter | Qt::AlignRight);

  main_layout->addLayout(header_layout);

  // main content
  main_layout->addSpacing(25);
  center_layout = new QStackedLayout();

  QHBoxLayout* statsAndSetup = new QHBoxLayout();
  statsAndSetup->setMargin(0);

  DriveStats* drive = new DriveStats;
  drive->setFixedSize(800, 800);
  statsAndSetup->addWidget(drive);

  SetupWidget* setup = new SetupWidget;
  statsAndSetup->addWidget(setup);

  QWidget* statsAndSetupWidget = new QWidget();
  statsAndSetupWidget->setLayout(statsAndSetup);

  center_layout->addWidget(statsAndSetupWidget);

  alerts_widget = new OffroadAlert();
  QObject::connect(alerts_widget, &OffroadAlert::closeAlerts, this, &OffroadHome::closeAlerts);
  center_layout->addWidget(alerts_widget);
  center_layout->setAlignment(alerts_widget, Qt::AlignCenter);

  main_layout->addLayout(center_layout, 1);

  // set up refresh timer
  timer = new QTimer(this);
  QObject::connect(timer, &QTimer::timeout, this, &OffroadHome::refresh);
  timer->start(10 * 1000);

  setLayout(main_layout);
  setStyleSheet(R"(
    OffroadHome {
      background-color: black;
    }
    * {
     color: white;
    }
  )");
}

void OffroadHome::showEvent(QShowEvent *event) {
  refresh();
}

void OffroadHome::openAlerts() {
  center_layout->setCurrentIndex(1);
}

void OffroadHome::closeAlerts() {
  center_layout->setCurrentIndex(0);
}

void OffroadHome::refresh() {
  bool first_refresh = !date->text().size();
  if (!isVisible() && !first_refresh) {
    return;
  }

  date->setText(QDateTime::currentDateTime().toString("dddd, MMMM d"));

  // update alerts

  alerts_widget->refresh();
  if (!alerts_widget->alertCount && !alerts_widget->updateAvailable) {
    closeAlerts();
    alert_notification->setVisible(false);
    return;
  }

  if (alerts_widget->updateAvailable) {
    alert_notification->setText("UPDATE");
  } else {
    int alerts = alerts_widget->alertCount;
    alert_notification->setText(QString::number(alerts) + " ALERT" + (alerts == 1 ? "" : "S"));
  }

  if (!alert_notification->isVisible() && !first_refresh) {
    openAlerts();
  }
  alert_notification->setVisible(true);

  // Red background for alerts, blue for update available
  QString style = QString(R"(
    padding: 15px;
    padding-left: 30px;
    padding-right: 30px;
    border: 1px solid;
    border-radius: 5px;
    font-size: 40px;
    font-weight: 500;
    background-color: #E22C2C;
  )");
  if (alerts_widget->updateAvailable) {
    style.replace("#E22C2C", "#364DEF");
  }
  alert_notification->setStyleSheet(style);
}
<|endoftext|>


<commit_before>//
//
//

#include "WwwMode.h"
#include "SystemMethods.h"
#include "Constants.h"

WwwMode::WwwMode()
{
	state = 0;
	timeLeft = 0;
}
WwwMode::~WwwMode(){}

void WwwMode::PlayerButtonPush(int playerNumber)
{
	if (state == 1)
	{
		SystemMethodsObject.SetDisplayNumber(timeLeft);
		timeLeft --;
	}

	if (timeLeft == 10)
	{
		SystemMethodsObject.PlaySound(Constants.wwwTenSecondsLeftFrequency, Constants.signalPeriod);
	}

	if (timeLeft == 0)
	{
		SystemMethodsObject.PlaySound(Constants.wwwPeriodExpiredFrequency, Constants.signalPeriod);
		state = 0;
	}
}

void WwwMode::AdminButtonPush(int buttonNumber)
{
	if (buttonNumber == Constants.adminReset)
	{
		state = 0;
		timeLeft = 0;
	}
	else
	{
		if(buttonNumber == Constants.adminSet)
		{
			state = 1;
			timeLeft = 60;
			SystemMethodsObject.PlaySound(Constants.adminSignalPeriodFrequency, Constants.signalPeriod);
		}
	}
}
<commit_msg>WWW game mode fix<commit_after>//
//
//

#include "WwwMode.h"
#include "SystemMethods.h"
#include "Constants.h"

WwwMode::WwwMode()
{
	state = 0;
	timeLeft = 0;
}
WwwMode::~WwwMode(){}

void WwwMode::PlayerButtonPush(int playerNumber)
{
	if (state == 1)
	{
		SystemMethodsObject.SetDisplayNumber(timeLeft);
		timeLeft--;

		if (timeLeft == 9)
		{
			SystemMethodsObject.PlaySound(Constants.wwwTenSecondsLeftFrequency, Constants.signalPeriod);
		}

		if (timeLeft == 0)
		{
			SystemMethodsObject.PlaySound(Constants.wwwPeriodExpiredFrequency, Constants.signalPeriod);
			state = 0;
		}
	}
}

void WwwMode::AdminButtonPush(int buttonNumber)
{
	if (buttonNumber == Constants.adminReset)
	{
		state = 0;
		timeLeft = 0;
		SystemMethodsObject.SetDisplayNumber(-1);

	}
	else
	{
		if (buttonNumber == Constants.adminSet)
		{
			state = 1;
			timeLeft = 60;
			SystemMethodsObject.PlaySound(Constants.adminSignalPeriodFrequency, Constants.signalPeriod);
		}
	}
}
<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <string>
#include <limits>

#include <cxxtest/TestSuite.h>

#include "enfa.h"
#include "parser.h"
#include "resyntax/RegExp.h"

class MyTestSuite : public CxxTest::TestSuite {
  public:
    void test1() {
      std::string regexp = "(a|b)*c";
      // Parse a string to a RegExp AST.
      auto ast = tinygrep::parse(regexp);
      TS_ASSERT_EQUALS(ast.getType(), tinygrep::resyntax::RegExpEnum::kConcatenation);
      auto a_or_b_star = ast.getR1();
      auto c = ast.getR2();
      TS_ASSERT_EQUALS(a_or_b_star.getR1().getR2().getType(), tinygrep::resyntax::RegExpEnum::kLiteral);
      // Create a graph representation.
      auto regexp_test_graph = ast.to_graph();
      std::ofstream os_regexp("build/test_regexp_graph.gv");
      if (os_regexp.is_open()) {
        os_regexp << regexp_test_graph;
      }
      os_regexp.close(); // Generate EpsilonNFA from AST.
      auto enfautomaton = tinygrep::enfa::EpsilonNFA(ast);
      TS_ASSERT(enfautomaton.accepts("abbaaababc"));
      TS_ASSERT(enfautomaton.accepts("abc"));
      TS_ASSERT(enfautomaton.accepts("bac"));
      TS_ASSERT(enfautomaton.accepts("c"));
      TS_ASSERT(!enfautomaton.accepts("cc"));
      TS_ASSERT(!enfautomaton.accepts("abbaabababab"));
      TS_ASSERT(!enfautomaton.accepts("acc"));
      TS_ASSERT(!enfautomaton.accepts(""));

      auto enfa_test_graph = enfautomaton.to_graph();
      std::ofstream os_enfa("build/test_enfautomaton_graph.gv");
      if (os_enfa.is_open()) {
        os_enfa << enfa_test_graph;
      }
      os_enfa.close();
    }

    void runtestcase(const std::string& filepath) {
      std::ifstream testcase(filepath);
      bool testcase_file_available = testcase.is_open();
      TS_ASSERT(testcase_file_available);
      if (!testcase_file_available) {
        return;
      }
      // Ignore alphabet.
      testcase.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      // Read regex, create automaton.
      std::string regex;
      std::getline(testcase, regex);
      tinygrep::enfa::EpsilonNFA enfa(".*(" + regex + ").*");
      // Run searches.
      std::string search_line;
      while (getline(testcase, search_line)) {
        bool accept_flag = search_line[0] == '+'
                        || (search_line[0] != '-' && search_line.rfind("/\\") == std::string::npos);
        std::string fail_msg = "testcase: " + filepath + ", "
                             + "regexp: " + regex + ", "
                             + "string: \"" + search_line + "\", "
                             + "accept: " + (accept_flag?"T":"F") + ".";
        TSM_ASSERT(fail_msg, enfa.accepts(search_line) == accept_flag);
      }
      testcase.close();
    }

    void test2() {
      std::string testcase_prefix("testcase"),
                  testcase_postfix(".txt"),
                  testcase_path("test/manual-testcases/");
      std::vector<std::string> testcase_indices = {"1","2","4","5","10","11","15","16"};
      for (std::string testcase_id : testcase_indices) {
        runtestcase(testcase_path + testcase_prefix + testcase_id + testcase_postfix);
      }
    }

};
<commit_msg>Add ENFA graph generation to more tests.<commit_after>#include <fstream>
#include <iostream>
#include <string>
#include <limits>

#include <cxxtest/TestSuite.h>

#include "enfa.h"
#include "parser.h"
#include "resyntax/RegExp.h"

class MyTestSuite : public CxxTest::TestSuite {
  public:
    void test1() {
      std::string regexp = "(a|b)*c";
      // Parse a string to a RegExp AST.
      auto ast = tinygrep::parse(regexp);
      TS_ASSERT_EQUALS(ast.getType(), tinygrep::resyntax::RegExpEnum::kConcatenation);
      auto a_or_b_star = ast.getR1();
      auto c = ast.getR2();
      TS_ASSERT_EQUALS(a_or_b_star.getR1().getR2().getType(), tinygrep::resyntax::RegExpEnum::kLiteral);
      // Create a graph representation.
      auto regexp_test_graph = ast.to_graph();
      std::ofstream os_regexp("build/test_regexp_graph.gv");
      if (os_regexp.is_open()) {
        os_regexp << regexp_test_graph;
      }
      os_regexp.close();
      // Generate EpsilonNFA from AST.
      auto enfautomaton = tinygrep::enfa::EpsilonNFA(ast);
      TS_ASSERT(enfautomaton.accepts("abbaaababc"));
      TS_ASSERT(enfautomaton.accepts("abc"));
      TS_ASSERT(enfautomaton.accepts("bac"));
      TS_ASSERT(enfautomaton.accepts("c"));
      TS_ASSERT(!enfautomaton.accepts("cc"));
      TS_ASSERT(!enfautomaton.accepts("abbaabababab"));
      TS_ASSERT(!enfautomaton.accepts("acc"));
      TS_ASSERT(!enfautomaton.accepts(""));

      auto enfa_test_graph = enfautomaton.to_graph();
      std::ofstream os_enfa("build/test_enfautomaton_graph.gv");
      if (os_enfa.is_open()) {
        os_enfa << enfa_test_graph;
      }
      os_enfa.close();
    }

    void runtestcase(const std::string& testcase_name, const std::string& filepath) {
      std::ifstream testcase(filepath);
      bool testcase_file_available = testcase.is_open();
      TS_ASSERT(testcase_file_available);
      if (!testcase_file_available) {
        return;
      }
      // Ignore alphabet.
      testcase.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
      // Read regex, create automaton.
      std::string regex;
      std::getline(testcase, regex);
      tinygrep::enfa::EpsilonNFA enfa(".*(" + regex + ").*");

      // Create a graph representation.
      auto enfa_graph = enfa.to_graph();
      std::ofstream os_enfa("build/" + testcase_name + ".gv");
      if (os_enfa.is_open()) {
        os_enfa << enfa_graph;
      }
      os_enfa.close();

      // Run searches.
      std::string search_line;
      while (getline(testcase, search_line)) {
        bool accept_flag = search_line[0] == '+'
                        || (search_line[0] != '-' && search_line.rfind("/\\") == std::string::npos);
        std::string fail_msg = "testcase: " + filepath + ", "
                             + "regexp: " + regex + ", "
                             + "string: \"" + search_line + "\", "
                             + "accept: " + (accept_flag?"T":"F") + ".";
        TSM_ASSERT(fail_msg, enfa.accepts(search_line) == accept_flag);
      }
      testcase.close();
    }

    void test2() {
      std::string testcase_prefix("testcase"),
                  testcase_postfix(".txt"),
                  testcase_path("test/manual-testcases/");
      std::vector<std::string> testcase_indices = {"1","2","4","5","10","11","15","16"};
      for (std::string testcase_id : testcase_indices) {
        auto testcase_name = testcase_prefix + testcase_id;
        runtestcase(testcase_name, testcase_path + testcase_name + testcase_postfix);
      }
    }

};
<|endoftext|>


<commit_before>/*
 * Union Find
 *
 */

// version 1:
class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>>& positions) {
        vector<int> res;
        int cnt = 0;
        vector<int> roots(m * n, -1);
        vector<vector<int>> dirs{{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
        for (auto a : positions) {
            int id = n * a.first + a.second;
            roots[id] = id;
            ++cnt;
            for (auto dir : dirs) {
                int x = a.first + dir[0], y = a.second + dir[1], cur_id = n * x + y;
                if (x < 0 || x >= m || y < 0 || y >= n || roots[cur_id] == -1) continue;
                int p = findRoot(roots, cur_id), q = findRoot(roots, id);
                if (p != q) {
                    roots[p] = q;
                    --cnt;
                }
            }
            res.push_back(cnt);
        }
        return res;
    }
    int findRoot(vector<int>& roots, int id) {
        return (id == roots[id]) ? id : findRoot(roots, roots[id]);
    }
};

// version 2:
class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>>& positions) {
        vector<int> res;
        int cnt = 0;

        roots.resize(m*n);
        for(int i = 0; i < m*n; i++) roots[i] = -1;

        vector<vector<int>> dirs({{-1, 0}, {1, 0}, {0, -1}, {0, 1}});

        for(auto a : positions) {
            int id = n * a.first + a.second;
            cnt++;
            roots[id] = id;
            for(auto dir : dirs) {
                int x = a.first + dir[0], y = a.second + dir[1], cur_id = x * n + y;
                if(x < 0 || x >= m || y < 0 || y >= n || roots[cur_id] == -1) continue;
                int p = findRoot(cur_id), q = findRoot(id);
                if(p != q) {
                    roots[p] = q;
                    cnt--;
                }
            }
            res.push_back(cnt);
        }

        return res;
    }

private:
    vector<int> roots; // label the islane

    int findRoot(int id) {
        if(roots[id] == id) return id;
        return roots[id] = findRoot(roots[id]);
    }
};

// Conclusion:
// 为了解决这种陆地之间会合并的情况，最好能够将每个陆地都标记出其属于哪个岛屿，这样就会方便我们统计岛屿个数。
// 这种群组类问题，很适合使用联合查找 Union Find 来做，又叫并查集 Disjoint Set，LeetCode中使用这种解法
// 的题目还不少呢，比如Friend Circles，Graph Valid Tree，Redundant Connection II 等等。
//
// Reference:
// http://www.cnblogs.com/grandyang/p/5190419.html
//
// Union Find
// A union-find algorithm is an algorithm that performs two useful operations on such a data structure:
// Find: Determine which subset a particular element is in. This can be used for determining if two ele
//       ments are in the same subset.
// Union: Join two subsets into a single subset.

<commit_msg>Update 305.cpp<commit_after>/*
 * Union Find
 *
 */

// version 1:
class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>>& positions) {
        vector<int> res;
        int cnt = 0;
        vector<int> roots(m * n, -1);
        vector<vector<int>> dirs{{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
        for (auto a : positions) {
            int id = n * a.first + a.second;
            roots[id] = id;
            ++cnt;
            for (auto dir : dirs) {
                int x = a.first + dir[0], y = a.second + dir[1], cur_id = n * x + y;
                if (x < 0 || x >= m || y < 0 || y >= n || roots[cur_id] == -1) continue;
                int p = findRoot(roots, cur_id), q = findRoot(roots, id);
                if (p != q) {
                    roots[p] = q;
                    --cnt;
                }
            }
            res.push_back(cnt);
        }
        return res;
    }
    int findRoot(vector<int>& roots, int id) {
        return (id == roots[id]) ? id : findRoot(roots, roots[id]);
    }
};

// version 2:
class Solution {
public:
    vector<int> numIslands2(int m, int n, vector<pair<int, int>>& positions) {
        vector<int> res;
        int cnt = 0;

        roots.resize(m*n);
        for(int i = 0; i < m*n; i++) roots[i] = -1;

        vector<vector<int>> dirs({{-1, 0}, {1, 0}, {0, -1}, {0, 1}});

        for(auto a : positions) {
            int id = n * a.first + a.second;
            cnt++;
            roots[id] = id;
            for(auto dir : dirs) {
                int x = a.first + dir[0], y = a.second + dir[1], cur_id = x * n + y;
                if(x < 0 || x >= m || y < 0 || y >= n || roots[cur_id] == -1) continue;
                int p = findRoot(cur_id), q = findRoot(id);
                if(p != q) {
                    roots[p] = q;
                    cnt--;
                }
            }
            res.push_back(cnt);
        }

        return res;
    }

private:
    vector<int> roots; // label the islane

    int findRoot(int id) {
        if(roots[id] == id) return id;
        return roots[id] = findRoot(roots[id]);
    }
};

// Conclusion:
// 为了解决这种陆地之间会合并的情况，最好能够将每个陆地都标记出其属于哪个岛屿，这样就会方便我们统计岛屿个数。
// 这种群组类问题，很适合使用联合查找 Union Find 来做，又叫并查集 Disjoint Set，LeetCode中使用这种解法
// 的题目还不少呢，比如Friend Circles，Graph Valid Tree，Redundant Connection II 等等。
//
// 当标记一个新的陆地，首先岛屿数自增1，再去检查四周相邻的四个cell，如果是陆地且不连通，则连通，同时岛屿数自减1。
//
// Reference:
// http://www.cnblogs.com/grandyang/p/5190419.html
//
// Union Find
// A union-find algorithm is an algorithm that performs two useful operations on such a data structure:
// Find: Determine which subset a particular element is in. This can be used for determining if two ele
//       ments are in the same subset.
// Union: Join two subsets into a single subset.

<|endoftext|>


<commit_before>/*
** Copyright 2015 Robert Fratto. See the LICENSE.txt file at the top-level
** directory of this distribution.
**
** Licensed under the MIT license <http://opensource.org/licenses/MIT>. This file
** may not be copied, modified, or distributed except according to those terms.
*/

#include <Grammar.h>
#include <Symtab.h>
#include <Analyzer.h>
#include <Errors.h>

#include <iostream>

Grammar* parseGrammar(const char* pathname)
{
	auto symtab = new Symtab();
	auto grammar = new Grammar(symtab);

	extern FILE* yyin;
	extern int yyparse(Grammar*);
	extern void yyflushbuffer();

	auto file = fopen(pathname, "r");
	if (file == nullptr)
	{
		std::cerr << "could not open " << pathname << " for reading\n";
		return nullptr;
	}

	yyflushbuffer();
	yyin = file;
	yyparse(grammar);

	fclose(file);
	return grammar;
}

int expectPass(const char* path)
{
	int retcode = 0;

	auto grammar = parseGrammar(path);

	Analyzer analyzer(grammar);

	try
	{
		if (analyzer.valid() == false)
		{
			retcode = 1;
		}
	}
	catch (std::exception& e)
	{
		retcode = 1;
	}

	delete grammar->getSymtab();
	delete grammar;

	return retcode;
}

template <typename T>
int getException(const char* path)
{
	int retcode = 1;

	auto grammar = parseGrammar(path);

	Analyzer analyzer(grammar);
	analyzer.setThrowExceptions(true);

	try
	{
		analyzer.valid();
	}
	catch (T& e)
	{
		retcode = 0;
	}
	catch (std::exception& e)
	{
		// Do nothing.
	}

	delete grammar->getSymtab();
	delete grammar;

	return retcode;
}

int main()
{
	int retcode = 0;

	if (getException<left_recursion_error>("grammars/left_recursive_2.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive_2.y\n";
		retcode = 1;
	}

	if (getException<left_recursion_error>("grammars/left_recursive_epsilon.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive_epsilon.y\n";
		retcode = 1;
	}

	if (getException<left_recursion_error>("grammars/left_recursive_indirect.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive_indirect.y\n";
		retcode = 1;
	}

	if (getException<left_recursion_error>("grammars/left_recursive.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive.y\n";
		retcode = 1;
	}

	if (getException<undefined_error>("grammars/undefined.y") == 1)
	{
		std::cerr << "failed: grammars/undefined.y\n";
		retcode = 1;
	}

	if (expectPass("grammars/unused.y") == 1)
	{
		std::cerr << "failed: grammars/unused.y\n";
		retcode = 1;
	}

	return retcode;
}
<commit_msg>Compute FIRST in unit tests.<commit_after>/*
** Copyright 2015 Robert Fratto. See the LICENSE.txt file at the top-level
** directory of this distribution.
**
** Licensed under the MIT license <http://opensource.org/licenses/MIT>. This file
** may not be copied, modified, or distributed except according to those terms.
*/

#include <Grammar.h>
#include <Symtab.h>
#include <Analyzer.h>
#include <Errors.h>

#include <iostream>

Grammar* parseGrammar(const char* pathname)
{
	auto symtab = new Symtab();
	auto grammar = new Grammar(symtab);

	extern FILE* yyin;
	extern int yyparse(Grammar*);
	extern void yyflushbuffer();

	auto file = fopen(pathname, "r");
	if (file == nullptr)
	{
		std::cerr << "could not open " << pathname << " for reading\n";
		return nullptr;
	}

	yyflushbuffer();
	yyin = file;
	yyparse(grammar);

	fclose(file);

	grammar->computeFirst();

	return grammar;
}

int expectPass(const char* path)
{
	int retcode = 0;

	auto grammar = parseGrammar(path);

	Analyzer analyzer(grammar);
	analyzer.printFirst();

	try
	{
		if (analyzer.valid() == false)
		{
			retcode = 1;
		}
	}
	catch (std::exception& e)
	{
		retcode = 1;
	}

	delete grammar->getSymtab();
	delete grammar;

	return retcode;
}

template <typename T>
int getException(const char* path)
{
	int retcode = 1;

	auto grammar = parseGrammar(path);

	Analyzer analyzer(grammar);
	analyzer.setThrowExceptions(true);
	analyzer.printFirst();

	try
	{
		analyzer.valid();
	}
	catch (T& e)
	{
		retcode = 0;
	}
	catch (std::exception& e)
	{
		// Do nothing.
	}

	delete grammar->getSymtab();
	delete grammar;

	return retcode;
}

int main()
{
	int retcode = 0;

	if (getException<left_recursion_error>("grammars/left_recursive_2.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive_2.y\n";
		retcode = 1;
	}

	if (getException<left_recursion_error>("grammars/left_recursive_epsilon.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive_epsilon.y\n";
		retcode = 1;
	}

	if (getException<left_recursion_error>("grammars/left_recursive_indirect.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive_indirect.y\n";
		retcode = 1;
	}

	if (getException<left_recursion_error>("grammars/left_recursive.y") == 1)
	{
		std::cerr << "failed: grammars/left_recursive.y\n";
		retcode = 1;
	}

	if (getException<undefined_error>("grammars/undefined.y") == 1)
	{
		std::cerr << "failed: grammars/undefined.y\n";
		retcode = 1;
	}

	if (expectPass("grammars/unused.y") == 1)
	{
		std::cerr << "failed: grammars/unused.y\n";
		retcode = 1;
	}

	return retcode;
}
<|endoftext|>


<commit_before>/*
 * Chrome Token Signing Native Host
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "PKCS11Path.h"
#include "BinaryUtils.h"
#include "Logger.h"

#ifdef _WIN32
#undef UNICODE
#include <Shlobj.h>
#include <Shlwapi.h>
#include <Knownfolders.h>
#include <winscard.h>
#elif defined __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#include <unistd.h>
#else
#include <winscard.h>
#include <unistd.h>
#endif

#include <cstring>
#include <map>

std::vector<std::string> PKCS11Path::atrList() {
	SCARDCONTEXT hContext = 0;
	std::vector<std::string> result;
	LONG err = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hContext);
	if (err != SCARD_S_SUCCESS) {
		_log("SCardEstablishContext ERROR: %x", err);
		return result;
	}

	DWORD size = 0;
	err = SCardListReaders(hContext, nullptr, nullptr, &size);
	if (err != SCARD_S_SUCCESS || !size) {
		_log("SCardListReaders || !size ERROR: %x", err);
		SCardReleaseContext(hContext);
		return result;
	}

	std::string readers(size, 0);
	err = SCardListReaders(hContext, nullptr, &readers[0], &size);
	readers.resize(size);
	if (err != SCARD_S_SUCCESS) {
		_log("SCardListReaders ERROR: %x", err);
		SCardReleaseContext(hContext);
		return result;
	}

    std::vector<SCARD_READERSTATE> list;
    for (const char *name = readers.c_str(); *name != 0; name += strlen(name) + 1) {
        _log("found reader: %s", name);
        list.push_back({name, 0, 0, 0, 0, 0});
    }

    err = SCardGetStatusChange(hContext, 0, list.data(), DWORD(list.size()));
    if (err != SCARD_S_SUCCESS)
        _log("SCardGetStatusChange ERROR: %x", err);
    for(const SCARD_READERSTATE &state: list)
    {
        if (state.dwEventState & SCARD_STATE_PRESENT)
        {
            std::string atr = BinaryUtils::bin2hex(state.rgbAtr, state.cbAtr);
            result.push_back(atr);
            _log("Set ATR = %s for reader %s", atr.c_str(), state.szReader);
        }
    }

    SCardReleaseContext(hContext);
    return result;
}

PKCS11Path::Params PKCS11Path::getPkcs11ModulePath() {
#ifdef _WIN32
    // Use PKCS11 driver on windows to avoid PIN buffering
    static const std::string litPath = [] {
        PWSTR programFilesX86 = 0;
        SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, NULL, &programFilesX86);
        std::wstring path = programFilesX86;
        CoTaskMemFree(programFilesX86);
        if (PathFileExistsW((path + L"\\PWPW\\pwpw-card-pkcs11.dll").c_str()))
            path += L"\\PWPW\\pwpw-card-pkcs11.dll";
        else
            path += L"\\CryptoTech\\CryptoCard\\CCPkiP11.dll";
        int size = WideCharToMultiByte(CP_UTF8, 0, path.c_str(), DWORD(path.size()), nullptr, 0, nullptr, nullptr);
        std::string result(size, 0);
        WideCharToMultiByte(CP_UTF8, 0, path.c_str(), DWORD(path.size()), &result[0], size, nullptr, nullptr);
        return result;
    }();
#elif defined __APPLE__
    static const std::string openscPath("/Library/OpenSC/lib/opensc-pkcs11.so");
    static const std::string estPath = openscPath;
    static const std::string latPath("/Library/latvia-eid/lib/otlv-pkcs11.so");
    static const std::string finPath("/Library/mPolluxDigiSign/libcryptoki.dylib");
    static const std::string lit1Path("/Library/Security/tokend/CCSuite.tokend/Contents/Frameworks/libccpkip11.dylib");
    static const std::string lit2Path("/Library/PWPW-Card/pwpw-card-pkcs11.so");
    static const std::string litPath = access(lit1Path.c_str(), F_OK) == 0 ? lit1Path : lit2Path;
    static const std::string eTokenPath("/Library/Frameworks/eToken.framework/Versions/Current/libeToken.dylib");
#else
    static const std::string openscPath("opensc-pkcs11.so");
    static const std::string estPath = openscPath;
    static const std::string latPath("otlv-pkcs11.so");
    static const std::string finPath("libcryptoki.so");
    static const std::string lit1Path("/usr/lib/ccs/libccpkip11.so");
    static const std::string lit2Path("pwpw-card-pkcs11.so");
    static const std::string litPath = access(lit1Path.c_str(), F_OK) == 0 ? lit1Path : lit2Path;
    static const std::string eTokenPath("/usr/local/lib/libeTPkcs11.dylib");
#endif
    static const std::map<std::string, Params> m = {
#ifdef _WIN32
        {"3BFD1800008031FE4553434536302D43443134352D46CD", {"C:\\Windows\\System32\\aetpkss1.dll", "PIN", "PIN"}},
#else
        {"3BFE1800008031FE454573744549442076657220312E30A8", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_COLD_DEV1_ATR
        {"3BFE1800008031FE45803180664090A4561B168301900086", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_WARM_DEV1_ATR
        {"3BFE1800008031FE45803180664090A4162A0083019000E1", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_WARM_DEV2_ATR
        {"3BFE1800008031FE45803180664090A4162A00830F9000EF", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_WARM_DEV3_ATR
        {"3BFA1800008031FE45FE654944202F20504B4903", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3.5_COLD_ATR

        {"3BDD18008131FE45904C41545649412D65494490008C", {latPath, "PIN1", "PIN2"}},

        {"3B7B940000806212515646696E454944", {finPath, "PIN1", "PIN2"}},
        {"3B7F9600008031B865B0850300EF1200F6829000", {finPath, "PIN1", "PIN2"}},

        {"3BD5180081313A7D8073C8211030", {eTokenPath, "PIN", "PIN"}},
        {"3BD518008131FE7D8073C82110F4", {eTokenPath, "PIN", "PIN"}},
#endif
        {"3BF81300008131FE45536D617274417070F8", {litPath, "PIN", "PIN"}},
        {"3B7D94000080318065B08311C0A983009000", {litPath, "PIN", "PIN"}},
        {"3B7D94000080318065B0831100C883009000", {litPath, "PIN", "PIN"}},
        {"3B9F9681B1FE451F070064051EB20031B0739621DB00900050", {litPath, "PIN", "PIN"}},
        {"3B9F90801FC30068104405014649534531C800000000", {litPath, "PIN", "PIN"}},
    };

    const std::vector<std::string> list = atrList();
    for (const std::string &atr : list) {
        auto it = m.find(atr);
        if (it != m.end())
            return it->second;
    }
#ifdef _WIN32
    return Params();
#else
    if (!list.empty())
        _log("Unknown ATR '%s' using default module '%s'", list[0].c_str(), openscPath.c_str());
    return {openscPath, "PIN", "PIN"};
#endif
}
<commit_msg>Add Belgium middleware paths (#72)<commit_after>/*
 * Chrome Token Signing Native Host
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "PKCS11Path.h"
#include "BinaryUtils.h"
#include "Logger.h"

#ifdef _WIN32
#undef UNICODE
#include <Shlobj.h>
#include <Shlwapi.h>
#include <Knownfolders.h>
#include <winscard.h>
#elif defined __APPLE__
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#include <unistd.h>
#else
#include <winscard.h>
#include <unistd.h>
#endif

#include <cstring>
#include <map>

std::vector<std::string> PKCS11Path::atrList() {
	SCARDCONTEXT hContext = 0;
	std::vector<std::string> result;
	LONG err = SCardEstablishContext(SCARD_SCOPE_USER, nullptr, nullptr, &hContext);
	if (err != SCARD_S_SUCCESS) {
		_log("SCardEstablishContext ERROR: %x", err);
		return result;
	}

	DWORD size = 0;
	err = SCardListReaders(hContext, nullptr, nullptr, &size);
	if (err != SCARD_S_SUCCESS || !size) {
		_log("SCardListReaders || !size ERROR: %x", err);
		SCardReleaseContext(hContext);
		return result;
	}

	std::string readers(size, 0);
	err = SCardListReaders(hContext, nullptr, &readers[0], &size);
	readers.resize(size);
	if (err != SCARD_S_SUCCESS) {
		_log("SCardListReaders ERROR: %x", err);
		SCardReleaseContext(hContext);
		return result;
	}

    std::vector<SCARD_READERSTATE> list;
    for (const char *name = readers.c_str(); *name; name += strlen(name) + 1) {
        _log("found reader: %s", name);
        list.push_back({name, 0, 0, 0, 0, 0});
    }

    err = SCardGetStatusChange(hContext, 0, list.data(), DWORD(list.size()));
    if (err != SCARD_S_SUCCESS)
        _log("SCardGetStatusChange ERROR: %x", err);
    for(const SCARD_READERSTATE &state: list)
    {
        if (state.dwEventState & SCARD_STATE_PRESENT)
        {
            std::string atr = BinaryUtils::bin2hex(state.rgbAtr, state.cbAtr);
            result.push_back(atr);
            _log("Set ATR = %s for reader %s", atr.c_str(), state.szReader);
        }
    }

    SCardReleaseContext(hContext);
    return result;
}

PKCS11Path::Params PKCS11Path::getPkcs11ModulePath() {
#ifdef _WIN32
    // Use PKCS11 driver on windows to avoid PIN buffering
    static const std::string litPath = [] {
        PWSTR programFilesX86 = 0;
        SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, NULL, &programFilesX86);
        std::wstring path = programFilesX86;
        CoTaskMemFree(programFilesX86);
        if (PathFileExistsW((path + L"\\PWPW\\pwpw-card-pkcs11.dll").c_str()))
            path += L"\\PWPW\\pwpw-card-pkcs11.dll";
        else
            path += L"\\CryptoTech\\CryptoCard\\CCPkiP11.dll";
        int size = WideCharToMultiByte(CP_UTF8, 0, path.c_str(), DWORD(path.size()), nullptr, 0, nullptr, nullptr);
        std::string result(size, 0);
        WideCharToMultiByte(CP_UTF8, 0, path.c_str(), DWORD(path.size()), &result[0], size, nullptr, nullptr);
        return result;
    }();
#elif defined __APPLE__
    static const std::string openscPath("/Library/OpenSC/lib/opensc-pkcs11.so");
    static const std::string estPath = openscPath;
    static const std::string latPath("/Library/latvia-eid/lib/otlv-pkcs11.so");
    static const std::string finPath("/Library/mPolluxDigiSign/libcryptoki.dylib");
    static const std::string lit1Path("/Library/Security/tokend/CCSuite.tokend/Contents/Frameworks/libccpkip11.dylib");
    static const std::string lit2Path("/Library/PWPW-Card/pwpw-card-pkcs11.so");
    static const std::string litPath = access(lit1Path.c_str(), F_OK) == 0 ? lit1Path : lit2Path;
    static const std::string belPath("/usr/local/lib/beid-pkcs11.bundle/Contents/MacOS/libbeidpkcs11.dylib");
    static const std::string eTokenPath("/Library/Frameworks/eToken.framework/Versions/Current/libeToken.dylib");
#else
    static const std::string openscPath("opensc-pkcs11.so");
    static const std::string estPath = openscPath;
    static const std::string latPath("otlv-pkcs11.so");
    static const std::string finPath("libcryptoki.so");
    static const std::string lit1Path("/usr/lib/ccs/libccpkip11.so");
    static const std::string lit2Path("pwpw-card-pkcs11.so");
    static const std::string litPath = access(lit1Path.c_str(), F_OK) == 0 ? lit1Path : lit2Path;
    static const std::string belPath("libbeidpkcs11.so.0");
    static const std::string eTokenPath("/usr/local/lib/libeTPkcs11.dylib");
#endif
    static const std::map<std::string, Params> m = {
#ifdef _WIN32
        {"3BFD1800008031FE4553434536302D43443134352D46CD", {"C:\\Windows\\System32\\aetpkss1.dll", "PIN", "PIN"}},
#else
        {"3BFE1800008031FE454573744549442076657220312E30A8", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_COLD_DEV1_ATR
        {"3BFE1800008031FE45803180664090A4561B168301900086", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_WARM_DEV1_ATR
        {"3BFE1800008031FE45803180664090A4162A0083019000E1", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_WARM_DEV2_ATR
        {"3BFE1800008031FE45803180664090A4162A00830F9000EF", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3_WARM_DEV3_ATR
        {"3BFA1800008031FE45FE654944202F20504B4903", {estPath, "PIN1", "PIN2"}}, //ESTEID_V3.5_COLD_ATR

        {"3BDD18008131FE45904C41545649412D65494490008C", {latPath, "PIN1", "PIN2"}},

        {"3B7B940000806212515646696E454944", {finPath, "PIN1", "PIN2"}},
        {"3B7F9600008031B865B0850300EF1200F6829000", {finPath, "PIN1", "PIN2"}},

        {"3B9813400AA503010101AD1311", {belPath, "PIN", "PIN"}},

        {"3BD5180081313A7D8073C8211030", {eTokenPath, "PIN", "PIN"}},
        {"3BD518008131FE7D8073C82110F4", {eTokenPath, "PIN", "PIN"}},
#endif
        {"3BF81300008131FE45536D617274417070F8", {litPath, "PIN", "PIN"}},
        {"3B7D94000080318065B08311C0A983009000", {litPath, "PIN", "PIN"}},
        {"3B7D94000080318065B0831100C883009000", {litPath, "PIN", "PIN"}},
        {"3B9F9681B1FE451F070064051EB20031B0739621DB00900050", {litPath, "PIN", "PIN"}},
        {"3B9F90801FC30068104405014649534531C800000000", {litPath, "PIN", "PIN"}},
    };

    const std::vector<std::string> list = atrList();
    for (const std::string &atr : list) {
        auto it = m.find(atr);
        if (it != m.end())
            return it->second;
    }
#ifdef _WIN32
    return Params();
#else
    if (!list.empty())
        _log("Unknown ATR '%s' using default module '%s'", list[0].c_str(), openscPath.c_str());
    return {openscPath, "PIN", "PIN"};
#endif
}
<|endoftext|>


<commit_before>#include "stdafx.h"

App app;

std::string g_type;

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = lengthSq(it.xyz);
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App()
{
	meshId = MeshMan::INVALID_MMID;
}

static void DrawSprites()
{
	matrixStack.Reset();
	SpriteCommands cmds;
	SpriteCommand cmd;
	cmd.color = 0xffffffff;
	cmd.quad = Vec4(0, 0, 256, 256);
	cmd.tex = texMan.Create("jiji.dds");
	matrixStack.Mul(translate(64, 64, 0));
	for (int x = 0; x < 3; x++) {
		matrixStack.Push();
		for (int y = 0; y < 3; y++) {
			matrixStack.Push();
			matrixStack.Mul(q2m(Quat(Vec3(0, 0, 1), (x + y) * (float)M_PI / 3)));
			matrixStack.Mul(scale(0.5));
			matrixStack.Mul(translate(-128, -128, 0));
			matrixMan.Get(MatrixMan::WORLD, cmd.matW);
			matrixStack.Pop();
			matrixStack.Mul(translate(0, 128, 0));
			cmds.push_back(cmd);
		}
		matrixStack.Pop();
		matrixStack.Mul(translate(128, 0, 0));
	}
	spriteRenderer.Draw(cmds);
}

void App::Draw()
{
	afDepthStencilMode(true);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	waterSurface.Draw();

	afDepthStencilMode(true);
	afBlendMode(BM_NONE);

	matrixMan.Set(MatrixMan::WORLD, Mat());
	matrixMan.Set(MatrixMan::VIEW, devCamera.CalcViewMatrix());

	ivec2 scrSize = systemMetrics.GetScreenSize();

	float dist = devCamera.GetDistance();

	float f = dist * 1000;
	float n = dist / 1000;
	float aspect = (float)scrSize.x / scrSize.y;
	Mat proj = perspective(45, aspect, n, f);
	matrixMan.Set(MatrixMan::PROJ, proj);

	MeshXAnimResult r;
	MeshX* mesh = (MeshX*)meshMan.Get(meshId);
	if (mesh) {
		mesh->CalcAnimation(0, GetTime(), r);
//		mesh->Draw(r, Mat());
		mesh->Draw(r, translate(0, radius * 1.5f, 0) * q2m(Quat(Vec3(0, 0, 1.0f), (float)(GetTime() * M_PI))));
		mesh->Draw(r, translate(radius * 2.0f, 0, 0) * q2m(Quat(Vec3(0, 1.0f, 0), (float)(GetTime() * M_PI))));
	}
	meshRenderer.Flush();
	DrawSprites();
	fontMan.Render();
}

void App::Init()
{
//	void LuaBindTest();
//	LuaBindTest();

	ivec2 scrSize = systemMetrics.GetScreenSize();
    glViewport(0, 0, scrSize.x, scrSize.y);

	glClearColor(0.0f, 0.2f, 0.5f, 1.0f);
	afDepthStencilMode(true);

	meshRenderer.Create();
	waterSurface.Init();
	fontMan.Init();
	spriteRenderer.Init();
	luaMan.Create();

	LoadMesh("jiji.x");
}

void App::LoadMesh(const char* fileName)
{
	meshId = meshMan.Create(fileName);
	MeshX* mesh = (MeshX*)meshMan.Get(meshId);
	if (mesh) {
		radius = CalcRadius(mesh);
		float scale = std::max(0.00001f, radius);
		devCamera.SetDistance(scale * 3);
	}
	g_type = "mesh";
}

void App::OnTap(float x, float y)
{
	waterSurface.CreateRipple(Vec2(x, y));
}

void App::Destroy()
{
	luaMan.Destroy();
	spriteRenderer.Destroy();
	texMan.Destroy();
	shaderMan.Destroy();
	waterSurface.Destroy();
	fontMan.Destroy();
	meshRenderer.Destroy();
	meshMan.Destroy();
	meshId = MeshMan::INVALID_MMID;
}

void App::Update()
{
	luaMan.Update();
	waterSurface.Update();
	fps.Update();
	fontMan.DrawString(Vec2(20, 40), 20, SPrintf("FPS: %f", fps.Get()));
}
<commit_msg>wrap time to remove precision artifacts<commit_after>#include "stdafx.h"

App app;

std::string g_type;

static float CalcRadius(const Mesh* m)
{
	const Block& b = m->GetRawDatas();
	float maxSq = 0;
	for (auto& it : b.vertices) {
		float sq = lengthSq(it.xyz);
		maxSq = std::max(maxSq, sq);
	}
	return sqrt(maxSq);
}

App::App()
{
	meshId = MeshMan::INVALID_MMID;
}

static void DrawSprites()
{
	matrixStack.Reset();
	SpriteCommands cmds;
	SpriteCommand cmd;
	cmd.color = 0xffffffff;
	cmd.quad = Vec4(0, 0, 256, 256);
	cmd.tex = texMan.Create("jiji.dds");
	matrixStack.Mul(translate(64, 64, 0));
	for (int x = 0; x < 3; x++) {
		matrixStack.Push();
		for (int y = 0; y < 3; y++) {
			matrixStack.Push();
			matrixStack.Mul(q2m(Quat(Vec3(0, 0, 1), (x + y) * (float)M_PI / 3)));
			matrixStack.Mul(scale(0.5));
			matrixStack.Mul(translate(-128, -128, 0));
			matrixMan.Get(MatrixMan::WORLD, cmd.matW);
			matrixStack.Pop();
			matrixStack.Mul(translate(0, 128, 0));
			cmds.push_back(cmd);
		}
		matrixStack.Pop();
		matrixStack.Mul(translate(128, 0, 0));
	}
	spriteRenderer.Draw(cmds);
}

void App::Draw()
{
	afDepthStencilMode(true);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	waterSurface.Draw();

	afDepthStencilMode(true);
	afBlendMode(BM_NONE);

	matrixMan.Set(MatrixMan::WORLD, Mat());
	matrixMan.Set(MatrixMan::VIEW, devCamera.CalcViewMatrix());

	ivec2 scrSize = systemMetrics.GetScreenSize();

	float dist = devCamera.GetDistance();

	float f = dist * 1000;
	float n = dist / 1000;
	float aspect = (float)scrSize.x / scrSize.y;
	Mat proj = perspective(45, aspect, n, f);
	matrixMan.Set(MatrixMan::PROJ, proj);

	MeshXAnimResult r;
	MeshX* mesh = (MeshX*)meshMan.Get(meshId);
	if (mesh) {
		double now = GetTime();
		mesh->CalcAnimation(0, now, r);
		float wrappedTime = float(now - floor(now));
		auto normToRad = [](float n) { return n * float(M_PI * 2); };
		mesh->Draw(r, translate(0, radius * 1.5f, 0) * q2m(Quat(Vec3(0, 0, 1.0f), normToRad(wrappedTime))));
		mesh->Draw(r, translate(radius * 2.0f, 0, 0) * q2m(Quat(Vec3(0, 1.0f, 0), normToRad(wrappedTime))));
	}
	meshRenderer.Flush();
	DrawSprites();
	fontMan.Render();
}

void App::Init()
{
//	void LuaBindTest();
//	LuaBindTest();

	ivec2 scrSize = systemMetrics.GetScreenSize();
    glViewport(0, 0, scrSize.x, scrSize.y);

	glClearColor(0.0f, 0.2f, 0.5f, 1.0f);
	afDepthStencilMode(true);

	meshRenderer.Create();
	waterSurface.Init();
	fontMan.Init();
	spriteRenderer.Init();
	luaMan.Create();

	LoadMesh("jiji.x");
}

void App::LoadMesh(const char* fileName)
{
	meshId = meshMan.Create(fileName);
	MeshX* mesh = (MeshX*)meshMan.Get(meshId);
	if (mesh) {
		radius = CalcRadius(mesh);
		float scale = std::max(0.00001f, radius);
		devCamera.SetDistance(scale * 3);
	}
	g_type = "mesh";
}

void App::OnTap(float x, float y)
{
	waterSurface.CreateRipple(Vec2(x, y));
}

void App::Destroy()
{
	luaMan.Destroy();
	spriteRenderer.Destroy();
	texMan.Destroy();
	shaderMan.Destroy();
	waterSurface.Destroy();
	fontMan.Destroy();
	meshRenderer.Destroy();
	meshMan.Destroy();
	meshId = MeshMan::INVALID_MMID;
}

void App::Update()
{
	luaMan.Update();
	waterSurface.Update();
	fps.Update();
	fontMan.DrawString(Vec2(20, 40), 20, SPrintf("FPS: %f", fps.Get()));
}
<|endoftext|>


<commit_before><commit_msg>svx: ExternalToolEdit: don't terminate if SystemShellExecute throws<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include "trace.hxx"
#include <tools/debug.hxx>

#if defined(DBG_UTIL)

//==============================================================================

//------------------------------------------------------------------------------
::osl::Mutex Tracer::s_aMapSafety;
::std::map< ::oslThreadIdentifier, INT32, ::std::less< ::osl::ThreadIdentifier > >
        Tracer::s_aThreadIndents;

//------------------------------------------------------------------------------
Tracer::Tracer(const char* _pBlockDescription)
    :m_sBlockDescription(_pBlockDescription)
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ]++;

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += m_sBlockDescription;
    sMessage += " {";
    DBG_TRACE(sMessage.GetBuffer());
}

//------------------------------------------------------------------------------
Tracer::~Tracer()
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = --s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ];

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += "} // ";
    sMessage += m_sBlockDescription;
    DBG_TRACE(sMessage.GetBuffer());
}

//------------------------------------------------------------------------------
void Tracer::TraceString(const char* _pMessage)
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ];

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += m_sBlockDescription;
    sMessage += ": ";
    sMessage += _pMessage;
    DBG_TRACE(sMessage.GetBuffer());
}

//------------------------------------------------------------------------------
void Tracer::TraceString1StringParam(const char* _pMessage, const char* _pParam)
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ];

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += m_sBlockDescription;
    sMessage += ": ";
    sMessage += _pMessage;
    DBG_TRACE1(sMessage.GetBuffer(), _pParam);
}
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Fix breakage in dbgutil-enabled build<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include "trace.hxx"
#include <tools/debug.hxx>

#if defined(DBG_UTIL)

//==============================================================================

//------------------------------------------------------------------------------
::osl::Mutex Tracer::s_aMapSafety;
::std::map< ::oslThreadIdentifier, INT32, ::std::less< oslThreadIdentifier > >
        Tracer::s_aThreadIndents;

//------------------------------------------------------------------------------
Tracer::Tracer(const char* _pBlockDescription)
    :m_sBlockDescription(_pBlockDescription)
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ]++;

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += m_sBlockDescription;
    sMessage += " {";
    DBG_TRACE(sMessage.GetBuffer());
}

//------------------------------------------------------------------------------
Tracer::~Tracer()
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = --s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ];

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += "} // ";
    sMessage += m_sBlockDescription;
    DBG_TRACE(sMessage.GetBuffer());
}

//------------------------------------------------------------------------------
void Tracer::TraceString(const char* _pMessage)
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ];

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += m_sBlockDescription;
    sMessage += ": ";
    sMessage += _pMessage;
    DBG_TRACE(sMessage.GetBuffer());
}

//------------------------------------------------------------------------------
void Tracer::TraceString1StringParam(const char* _pMessage, const char* _pParam)
{
    ::osl::MutexGuard aGuard(s_aMapSafety);
    INT32 nIndent = s_aThreadIndents[ ::osl::Thread::getCurrentIdentifier() ];

    ByteString sIndent;
    while (nIndent--)
        sIndent += '\t';

    ByteString sThread( ByteString::CreateFromInt32( (INT32)::osl::Thread::getCurrentIdentifier() ) );
    sThread += '\t';

    ByteString sMessage(sThread);
    sMessage += sIndent;
    sMessage += m_sBlockDescription;
    sMessage += ": ";
    sMessage += _pMessage;
    DBG_TRACE1(sMessage.GetBuffer(), _pParam);
}
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>