<commit_before>#include "socket.h"

// STL
#include <memory>

// PDTK
#include <cxxutils/error_helpers.h>
#include <cxxutils/colors.h>

namespace posix
{
  inline bool peercred(fd_t socket, proccred_t& cred, int timeout = 100) noexcept
    { return ::peercred(socket, cred, timeout) == posix::success_response; }
}

GenericSocket::GenericSocket(EDomain   domain,
                             EType     type,
                             EProtocol protocol,
                             int       flags) noexcept
  : GenericSocket(posix::socket(domain, type, protocol, flags)) { }

GenericSocket::GenericSocket(posix::fd_t socket) noexcept
  : m_connected(false), m_socket(socket)
{
  Object::connect(m_socket, EventFlags::Readable, this, &GenericSocket::read); // monitor socket connection
}

GenericSocket::~GenericSocket(void) noexcept { disconnect(); }

void GenericSocket::disconnect(void) noexcept
{
  if(m_selfaddr != EDomain::unspec)
  {
    ::unlink(m_selfaddr.sun_path);
    m_selfaddr = EDomain::unspec;
  }

  if(m_socket != posix::invalid_descriptor)
  {
    Object::enqueue(disconnected, m_socket);
    Object::disconnect(m_socket, EventFlags::Readable);
    posix::close(m_socket); // connection severed!
    m_socket = posix::invalid_descriptor;
  }

  m_connected = false;
}

bool ClientSocket::connect(const char *socket_path) noexcept
{
  flaw(m_connected, posix::warning,,false,
       "Client socket is already connected!")

  flaw(std::strlen(socket_path) >= sizeof(sockaddr_un::sun_path),posix::warning,,false,
       "socket_path exceeds the maximum path length, %lu bytes", sizeof(sockaddr_un::sun_path))

  posix::sockaddr_t peeraddr;
  proccred_t peercred;

  peeraddr = socket_path;
  peeraddr = EDomain::local;
  m_selfaddr = EDomain::unspec;

  flaw(!posix::connect(m_socket, peeraddr, peeraddr.size()), posix::warning,, false,
       "connect() failure: %s", std::strerror(errno)) // connect to peer process
  m_connected = true;

  flaw(!posix::peercred(m_socket, peercred), posix::warning,, false,
       "peercred() failure: %s", std::strerror(errno)) // get creditials of connected peer process

  Object::enqueue(connected, m_socket, peeraddr, peercred);
  return true;
}

bool ClientSocket::write(const vfifo& buffer, posix::fd_t fd) const noexcept
{
  msghdr header = {};
  iovec iov = {};
  std::unique_ptr<char> aux_buffer(new char[CMSG_SPACE(sizeof(int))]);

  header.msg_iov = &iov;
  header.msg_iovlen = 1;
  header.msg_control = aux_buffer.get();

  iov.iov_base = buffer.begin();
  iov.iov_len = buffer.size();

  header.msg_controllen = 0;

  if(fd != posix::invalid_descriptor) // if a file descriptor needs to be sent
  {
    header.msg_controllen = CMSG_SPACE(sizeof(int));
    cmsghdr* cmsg = CMSG_FIRSTHDR(&header);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = fd;
  }

  flaw(posix::sendmsg(m_socket, &header) == posix::error_response, posix::warning,,false,
       "sendmsg() failure: %s", std::strerror(errno))
  return true;
}

bool ClientSocket::read(posix::fd_t socket, EventData_t event) noexcept
{
  (void)event;
  flaw(m_socket != socket, posix::critical, std::exit(2), false,
       "An 'impossible' situation has occurred.")

  msghdr header = {};
  iovec iov = {};
  std::unique_ptr<char> aux_buffer(new char[CMSG_SPACE(sizeof(int))]);

  header.msg_iov = &iov;
  header.msg_iovlen = 1;
  header.msg_control = aux_buffer.get();

  iov.iov_base = m_buffer.begin();
  iov.iov_len = m_buffer.capacity();
  header.msg_controllen = CMSG_SPACE(sizeof(int));

  posix::ssize_t byte_count = posix::recvmsg(m_socket, &header, 0);

  flaw(byte_count == posix::error_response, posix::warning,, false,
       "recvmsg() failure: %s", std::strerror(errno))

  flaw(!byte_count, posix::information, disconnect(), false,
       "Socket disconnected.")

  flaw(!m_buffer.resize(byte_count), posix::severe, posix::error(std::errc::not_enough_memory), false,
       "Failed to resize buffer to %li bytes", byte_count)

  posix::fd_t fd = posix::invalid_descriptor;
  if(header.msg_controllen == CMSG_SPACE(sizeof(int)))
  {
    cmsghdr* cmsg = CMSG_FIRSTHDR(&header);
    if(cmsg->cmsg_level == SOL_SOCKET &&
       cmsg->cmsg_type == SCM_RIGHTS &&
       cmsg->cmsg_len == CMSG_LEN(sizeof(int)))
      fd = *reinterpret_cast<int*>(CMSG_DATA(cmsg));
  }
  else
  { flaw(header.msg_flags, posix::warning,, false,
         "error, message flags: 0x%04x", header.msg_flags) }

  Object::enqueue(newMessage, m_socket, m_buffer, fd);
  return true;
}

bool ServerSocket::bind(const char* socket_path, EDomain domain, int socket_backlog) noexcept
{
  flaw(m_connected, posix::warning,,false,
       "Server socket is already bound!")

  flaw(socket_path == nullptr,posix::warning,,false,
       "socket_path is a null value")

  flaw(std::strlen(socket_path) >= sizeof(sockaddr_un::sun_path),posix::warning,,false,
       "socket_path exceeds the maximum path length, %lu bytes", sizeof(sockaddr_un::sun_path))

  m_selfaddr = socket_path;
  m_selfaddr = domain;

  flaw(!posix::bind(m_socket, m_selfaddr, m_selfaddr.size()),posix::warning,,false,
       "Unable to bind to socket to %s: %s", socket_path, std::strerror(errno))
  m_connected = true;

  flaw(!posix::listen(m_socket, socket_backlog),posix::warning,,false,
       "Unable to listen to server socket: %s", std::strerror(errno))
  return true;
}

bool ServerSocket::peerData(posix::fd_t socket, posix::sockaddr_t* addr, proccred_t* creds) const noexcept
{
  auto peer = m_peers.find(socket);
  if(peer == m_peers.end())
    return false;

  if(addr != nullptr)
    *addr = peer->second.addr;
  if(creds != nullptr)
    *creds = peer->second.creds;
  return true;
}

void ServerSocket::acceptPeerRequest(posix::fd_t socket) noexcept
{
  if(m_peers.find(socket) != m_peers.end())
  {
    auto connection = m_connections.emplace(socket, socket).first;
    Object::connect(connection->second.disconnected, this, &ServerSocket::disconnectPeer);
    Object::connect(connection->second.newMessage, newPeerMessage);
    Object::enqueue(connectedPeer, socket);
  }
}

void ServerSocket::rejectPeerRequest(posix::fd_t socket) noexcept
{
  auto peer = m_peers.find(socket);
  if(peer != m_peers.end())
  {
    m_peers.erase(peer);
    posix::close(socket);
  }
}

void ServerSocket::disconnectPeer(posix::fd_t socket) noexcept
{
  m_peers.erase(socket);
  m_connections.erase(socket);
  Object::enqueue(disconnectedPeer, socket);
}

// accepts socket connections and then enqueues newPeerRequest
bool ServerSocket::read(posix::fd_t socket, EventData_t event) noexcept
{
  (void)event;
  flaw(m_socket != socket, posix::critical, std::exit(2), false,
       "An 'impossible' situation has occurred.")
  proccred_t peercred;
  posix::sockaddr_t peeraddr;
  socklen_t addrlen = 0;
  posix::fd_t fd = posix::accept(m_socket, peeraddr, &addrlen); // accept a new socket connection

  flaw(fd == posix::error_response, posix::warning,, false,
       "accept() failure: %s", std::strerror(errno))

  flaw(addrlen >= sizeof(sockaddr_un::sun_path), posix::severe,, false,
       "accept() implementation bug: %s", "address length exceeds availible storage");

  flaw(addrlen != peeraddr.size(), posix::warning,, false,
       "accept() implementation bug: %s", "address length does not match string length");

  flaw(!posix::peercred(fd, peercred), posix::warning,, false,
       "peercred() failure: %s", std::strerror(errno)) // get creditials of connected peer process

  m_peers.emplace(fd, peer_t(fd, peeraddr, peercred));
  Object::enqueue(newPeerRequest, fd, peeraddr, peercred);
  return true;
}

bool ServerSocket::write(posix::fd_t socket, const vfifo& buffer, posix::fd_t fd) const noexcept
{
  auto connection = m_connections.find(socket);
  if(connection != m_connections.end())
    return connection->second.write(buffer, fd);
  return false;
}

<commit_msg>include fix for osx<commit_after>#include "socket.h"

// STL
#include <memory>

// POSIX++
#include <cstdlib>

// PDTK
#include <cxxutils/error_helpers.h>
#include <cxxutils/colors.h>

namespace posix
{
  inline bool peercred(fd_t socket, proccred_t& cred, int timeout = 100) noexcept
    { return ::peercred(socket, cred, timeout) == posix::success_response; }
}

GenericSocket::GenericSocket(EDomain   domain,
                             EType     type,
                             EProtocol protocol,
                             int       flags) noexcept
  : GenericSocket(posix::socket(domain, type, protocol, flags)) { }

GenericSocket::GenericSocket(posix::fd_t socket) noexcept
  : m_connected(false), m_socket(socket)
{
  Object::connect(m_socket, EventFlags::Readable, this, &GenericSocket::read); // monitor socket connection
}

GenericSocket::~GenericSocket(void) noexcept { disconnect(); }

void GenericSocket::disconnect(void) noexcept
{
  if(m_selfaddr != EDomain::unspec)
  {
    ::unlink(m_selfaddr.sun_path);
    m_selfaddr = EDomain::unspec;
  }

  if(m_socket != posix::invalid_descriptor)
  {
    Object::enqueue(disconnected, m_socket);
    Object::disconnect(m_socket, EventFlags::Readable);
    posix::close(m_socket); // connection severed!
    m_socket = posix::invalid_descriptor;
  }

  m_connected = false;
}

bool ClientSocket::connect(const char *socket_path) noexcept
{
  flaw(m_connected, posix::warning,,false,
       "Client socket is already connected!")

  flaw(std::strlen(socket_path) >= sizeof(sockaddr_un::sun_path),posix::warning,,false,
       "socket_path exceeds the maximum path length, %lu bytes", sizeof(sockaddr_un::sun_path))

  posix::sockaddr_t peeraddr;
  proccred_t peercred;

  peeraddr = socket_path;
  peeraddr = EDomain::local;
  m_selfaddr = EDomain::unspec;

  flaw(!posix::connect(m_socket, peeraddr, peeraddr.size()), posix::warning,, false,
       "connect() failure: %s", std::strerror(errno)) // connect to peer process
  m_connected = true;

  flaw(!posix::peercred(m_socket, peercred), posix::warning,, false,
       "peercred() failure: %s", std::strerror(errno)) // get creditials of connected peer process

  Object::enqueue(connected, m_socket, peeraddr, peercred);
  return true;
}

bool ClientSocket::write(const vfifo& buffer, posix::fd_t fd) const noexcept
{
  msghdr header = {};
  iovec iov = {};
  std::unique_ptr<char> aux_buffer(new char[CMSG_SPACE(sizeof(int))]);

  header.msg_iov = &iov;
  header.msg_iovlen = 1;
  header.msg_control = aux_buffer.get();

  iov.iov_base = buffer.begin();
  iov.iov_len = buffer.size();

  header.msg_controllen = 0;

  if(fd != posix::invalid_descriptor) // if a file descriptor needs to be sent
  {
    header.msg_controllen = CMSG_SPACE(sizeof(int));
    cmsghdr* cmsg = CMSG_FIRSTHDR(&header);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = fd;
  }

  flaw(posix::sendmsg(m_socket, &header) == posix::error_response, posix::warning,,false,
       "sendmsg() failure: %s", std::strerror(errno))
  return true;
}

bool ClientSocket::read(posix::fd_t socket, EventData_t event) noexcept
{
  (void)event;
  flaw(m_socket != socket, posix::critical, std::exit(2), false,
       "An 'impossible' situation has occurred.")

  msghdr header = {};
  iovec iov = {};
  std::unique_ptr<char> aux_buffer(new char[CMSG_SPACE(sizeof(int))]);

  header.msg_iov = &iov;
  header.msg_iovlen = 1;
  header.msg_control = aux_buffer.get();

  iov.iov_base = m_buffer.begin();
  iov.iov_len = m_buffer.capacity();
  header.msg_controllen = CMSG_SPACE(sizeof(int));

  posix::ssize_t byte_count = posix::recvmsg(m_socket, &header, 0);

  flaw(byte_count == posix::error_response, posix::warning,, false,
       "recvmsg() failure: %s", std::strerror(errno))

  flaw(!byte_count, posix::information, disconnect(), false,
       "Socket disconnected.")

  flaw(!m_buffer.resize(byte_count), posix::severe, posix::error(std::errc::not_enough_memory), false,
       "Failed to resize buffer to %li bytes", byte_count)

  posix::fd_t fd = posix::invalid_descriptor;
  if(header.msg_controllen == CMSG_SPACE(sizeof(int)))
  {
    cmsghdr* cmsg = CMSG_FIRSTHDR(&header);
    if(cmsg->cmsg_level == SOL_SOCKET &&
       cmsg->cmsg_type == SCM_RIGHTS &&
       cmsg->cmsg_len == CMSG_LEN(sizeof(int)))
      fd = *reinterpret_cast<int*>(CMSG_DATA(cmsg));
  }
  else
  { flaw(header.msg_flags, posix::warning,, false,
         "error, message flags: 0x%04x", header.msg_flags) }

  Object::enqueue(newMessage, m_socket, m_buffer, fd);
  return true;
}

bool ServerSocket::bind(const char* socket_path, EDomain domain, int socket_backlog) noexcept
{
  flaw(m_connected, posix::warning,,false,
       "Server socket is already bound!")

  flaw(socket_path == nullptr,posix::warning,,false,
       "socket_path is a null value")

  flaw(std::strlen(socket_path) >= sizeof(sockaddr_un::sun_path),posix::warning,,false,
       "socket_path exceeds the maximum path length, %lu bytes", sizeof(sockaddr_un::sun_path))

  m_selfaddr = socket_path;
  m_selfaddr = domain;

  flaw(!posix::bind(m_socket, m_selfaddr, m_selfaddr.size()),posix::warning,,false,
       "Unable to bind to socket to %s: %s", socket_path, std::strerror(errno))
  m_connected = true;

  flaw(!posix::listen(m_socket, socket_backlog),posix::warning,,false,
       "Unable to listen to server socket: %s", std::strerror(errno))
  return true;
}

bool ServerSocket::peerData(posix::fd_t socket, posix::sockaddr_t* addr, proccred_t* creds) const noexcept
{
  auto peer = m_peers.find(socket);
  if(peer == m_peers.end())
    return false;

  if(addr != nullptr)
    *addr = peer->second.addr;
  if(creds != nullptr)
    *creds = peer->second.creds;
  return true;
}

void ServerSocket::acceptPeerRequest(posix::fd_t socket) noexcept
{
  if(m_peers.find(socket) != m_peers.end())
  {
    auto connection = m_connections.emplace(socket, socket).first;
    Object::connect(connection->second.disconnected, this, &ServerSocket::disconnectPeer);
    Object::connect(connection->second.newMessage, newPeerMessage);
    Object::enqueue(connectedPeer, socket);
  }
}

void ServerSocket::rejectPeerRequest(posix::fd_t socket) noexcept
{
  auto peer = m_peers.find(socket);
  if(peer != m_peers.end())
  {
    m_peers.erase(peer);
    posix::close(socket);
  }
}

void ServerSocket::disconnectPeer(posix::fd_t socket) noexcept
{
  m_peers.erase(socket);
  m_connections.erase(socket);
  Object::enqueue(disconnectedPeer, socket);
}

// accepts socket connections and then enqueues newPeerRequest
bool ServerSocket::read(posix::fd_t socket, EventData_t event) noexcept
{
  (void)event;
  flaw(m_socket != socket, posix::critical, std::exit(2), false,
       "An 'impossible' situation has occurred.")
  proccred_t peercred;
  posix::sockaddr_t peeraddr;
  socklen_t addrlen = 0;
  posix::fd_t fd = posix::accept(m_socket, peeraddr, &addrlen); // accept a new socket connection

  flaw(fd == posix::error_response, posix::warning,, false,
       "accept() failure: %s", std::strerror(errno))

  flaw(addrlen >= sizeof(sockaddr_un::sun_path), posix::severe,, false,
       "accept() implementation bug: %s", "address length exceeds availible storage");

  flaw(addrlen != peeraddr.size(), posix::warning,, false,
       "accept() implementation bug: %s", "address length does not match string length");

  flaw(!posix::peercred(fd, peercred), posix::warning,, false,
       "peercred() failure: %s", std::strerror(errno)) // get creditials of connected peer process

  m_peers.emplace(fd, peer_t(fd, peeraddr, peercred));
  Object::enqueue(newPeerRequest, fd, peeraddr, peercred);
  return true;
}

bool ServerSocket::write(posix::fd_t socket, const vfifo& buffer, posix::fd_t fd) const noexcept
{
  auto connection = m_connections.find(socket);
  if(connection != m_connections.end())
    return connection->second.write(buffer, fd);
  return false;
}

<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/views/event.h"

namespace views {

int Event::GetWindowsFlags() const {
  // TODO: need support for x1/x2.
  int result = 0;
  result |= (flags_ & EF_SHIFT_DOWN) ? MK_SHIFT : 0;
  result |= (flags_ & EF_CONTROL_DOWN) ? MK_CONTROL : 0;
  result |= (flags_ & EF_LEFT_BUTTON_DOWN) ? MK_LBUTTON : 0;
  result |= (flags_ & EF_MIDDLE_BUTTON_DOWN) ? MK_MBUTTON : 0;
  result |= (flags_ & EF_RIGHT_BUTTON_DOWN) ? MK_RBUTTON : 0;
  return result;
}

//static
int Event::ConvertWindowsFlags(UINT win_flags) {
  int r = 0;
  if (win_flags & MK_CONTROL)
    r |= EF_CONTROL_DOWN;
  if (win_flags & MK_SHIFT)
    r |= EF_SHIFT_DOWN;
  if (GetKeyState(VK_MENU) < 0)
    r |= EF_ALT_DOWN;
  if (win_flags & MK_LBUTTON)
    r |= EF_LEFT_BUTTON_DOWN;
  if (win_flags & MK_MBUTTON)
    r |= EF_MIDDLE_BUTTON_DOWN;
  if (win_flags & MK_RBUTTON)
    r |= EF_RIGHT_BUTTON_DOWN;
  return r;
}

KeyEvent::KeyEvent(EventType type, int ch, int repeat_count, int message_flags)
    : Event(type, GetKeyStateFlags()),
      character_(ch),
      repeat_count_(repeat_count),
      message_flags_(message_flags) {
      }

int KeyEvent::GetKeyStateFlags() const {
  // Windows Keyboard messages don't come with control key state as parameters
  // like mouse messages do, so we need to explicitly probe for these key
  // states.
  int flags = 0;
  if (GetKeyState(VK_MENU) & 0x80)
    flags |= Event::EF_ALT_DOWN;
  if (GetKeyState(VK_SHIFT) & 0x80)
    flags |= Event::EF_SHIFT_DOWN;
  if (GetKeyState(VK_CONTROL) & 0x80)
    flags |= Event::EF_CONTROL_DOWN;
  return flags;
}

bool KeyEvent::IsExtendedKey() const {
  return (message_flags_ & KF_EXTENDED) == KF_EXTENDED;
}

}  // namespace views
<commit_msg>Fix broken build.<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/views/event.h"

#include <windows.h>

namespace views {

int Event::GetWindowsFlags() const {
  // TODO: need support for x1/x2.
  int result = 0;
  result |= (flags_ & EF_SHIFT_DOWN) ? MK_SHIFT : 0;
  result |= (flags_ & EF_CONTROL_DOWN) ? MK_CONTROL : 0;
  result |= (flags_ & EF_LEFT_BUTTON_DOWN) ? MK_LBUTTON : 0;
  result |= (flags_ & EF_MIDDLE_BUTTON_DOWN) ? MK_MBUTTON : 0;
  result |= (flags_ & EF_RIGHT_BUTTON_DOWN) ? MK_RBUTTON : 0;
  return result;
}

//static
int Event::ConvertWindowsFlags(UINT win_flags) {
  int r = 0;
  if (win_flags & MK_CONTROL)
    r |= EF_CONTROL_DOWN;
  if (win_flags & MK_SHIFT)
    r |= EF_SHIFT_DOWN;
  if (GetKeyState(VK_MENU) < 0)
    r |= EF_ALT_DOWN;
  if (win_flags & MK_LBUTTON)
    r |= EF_LEFT_BUTTON_DOWN;
  if (win_flags & MK_MBUTTON)
    r |= EF_MIDDLE_BUTTON_DOWN;
  if (win_flags & MK_RBUTTON)
    r |= EF_RIGHT_BUTTON_DOWN;
  return r;
}

KeyEvent::KeyEvent(EventType type, int ch, int repeat_count, int message_flags)
    : Event(type, GetKeyStateFlags()),
      character_(ch),
      repeat_count_(repeat_count),
      message_flags_(message_flags) {
      }

int KeyEvent::GetKeyStateFlags() const {
  // Windows Keyboard messages don't come with control key state as parameters
  // like mouse messages do, so we need to explicitly probe for these key
  // states.
  int flags = 0;
  if (GetKeyState(VK_MENU) & 0x80)
    flags |= Event::EF_ALT_DOWN;
  if (GetKeyState(VK_SHIFT) & 0x80)
    flags |= Event::EF_SHIFT_DOWN;
  if (GetKeyState(VK_CONTROL) & 0x80)
    flags |= Event::EF_CONTROL_DOWN;
  return flags;
}

bool KeyEvent::IsExtendedKey() const {
  return (message_flags_ & KF_EXTENDED) == KF_EXTENDED;
}

}  // namespace views
<|endoftext|>


<commit_before>#include "box2dpulleyjoint.h"
#include "box2dbody.h"
#include "box2dworld.h"

Box2DPulleyJoint::Box2DPulleyJoint(QDeclarativeItem *parent) :
    Box2DJoint(parent),
    mPulleyJointDef(),
    mPulleyJoint(0)
{
}

float Box2DPulleyJoint::ratio() const
{
    return mPulleyJointDef.ratio;
}

void Box2DPulleyJoint::setRatio(float ratio)
{
    if (mPulleyJointDef.ratio == ratio)
        return;

    mPulleyJointDef.ratio = ratio;
    emit ratioChanged();
}

QPointF Box2DPulleyJoint::groundAnchorA() const
{
    return QPointF(mPulleyJointDef.groundAnchorA.x, -mPulleyJointDef.groundAnchorA.y);
}

void Box2DPulleyJoint::setGroundAnchorA(const QPointF &anchor)
{
    if (mPulleyJointDef.groundAnchorA == b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio))
        return;

    mPulleyJointDef.groundAnchorA = b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio);

    emit groundAnchorAChanged();
}

QPointF Box2DPulleyJoint::groundAnchorB() const
{
    return QPointF(mPulleyJointDef.groundAnchorB.x, -mPulleyJointDef.groundAnchorB.y);
}

void Box2DPulleyJoint::setGroundAnchorB(const QPointF &anchor)
{
    if (mPulleyJointDef.groundAnchorB == b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio))
        return;

    mPulleyJointDef.groundAnchorB = b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio);

    emit groundAnchorBChanged();
}

QPointF const Box2DPulleyJoint::reactionForce(float inv)
{
    const b2Vec2 rf = mPulleyJoint->GetReactionForce(inv);

    return QPointF(rf.x, rf.y);
}

float Box2DPulleyJoint::reactionTorque(float inv)
{
    return mPulleyJoint->GetReactionTorque(inv);
}

float Box2DPulleyJoint::getLengthA()
{
    return mPulleyJoint->GetLengthA();
}

float Box2DPulleyJoint::getLengthB()
{
    return mPulleyJoint->GetLengthB();
}

void Box2DPulleyJoint::createJoint()
{
    mPulleyJointDef.Initialize(bodyA()->body(), bodyB()->body(),
	mPulleyJointDef.groundAnchorA,mPulleyJointDef.groundAnchorB,
	bodyA()->body()->GetWorldCenter(), bodyB()->body()->GetWorldCenter(),
	mPulleyJointDef.ratio);
    mPulleyJointDef.collideConnected = collideConnected();

    mPulleyJoint = static_cast<b2PulleyJoint*>(world()->CreateJoint(&mPulleyJointDef));
    mInitializePending = false;
}

void Box2DPulleyJoint::nullifyJoint()
{
    mPulleyJoint = 0;
}

void Box2DPulleyJoint::cleanup(b2World *world)
{
    if (mPulleyJoint && bodyA() && bodyB()) {
        mPulleyJoint->SetUserData(0);
        world->DestroyJoint(mPulleyJoint);
        mPulleyJoint = 0;
    }
}
<commit_msg>PulleyJoint: Scale the length and also check the joint exists before using it.<commit_after>#include "box2dpulleyjoint.h"
#include "box2dbody.h"
#include "box2dworld.h"

Box2DPulleyJoint::Box2DPulleyJoint(QDeclarativeItem *parent) :
    Box2DJoint(parent),
    mPulleyJointDef(),
    mPulleyJoint(0)
{
}

float Box2DPulleyJoint::ratio() const
{
    return mPulleyJointDef.ratio;
}

void Box2DPulleyJoint::setRatio(float ratio)
{
    if (mPulleyJointDef.ratio == ratio)
        return;

    mPulleyJointDef.ratio = ratio;
    emit ratioChanged();
}

QPointF Box2DPulleyJoint::groundAnchorA() const
{
    return QPointF(mPulleyJointDef.groundAnchorA.x, -mPulleyJointDef.groundAnchorA.y);
}

void Box2DPulleyJoint::setGroundAnchorA(const QPointF &anchor)
{
    if (mPulleyJointDef.groundAnchorA == b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio))
        return;

    mPulleyJointDef.groundAnchorA = b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio);

    emit groundAnchorAChanged();
}

QPointF Box2DPulleyJoint::groundAnchorB() const
{
    return QPointF(mPulleyJointDef.groundAnchorB.x, -mPulleyJointDef.groundAnchorB.y);
}

void Box2DPulleyJoint::setGroundAnchorB(const QPointF &anchor)
{
    if (mPulleyJointDef.groundAnchorB == b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio))
        return;

    mPulleyJointDef.groundAnchorB = b2Vec2(anchor.x() / scaleRatio, -anchor.y() / scaleRatio);

    emit groundAnchorBChanged();
}

QPointF const Box2DPulleyJoint::reactionForce(float inv)
{
    const b2Vec2 rf = mPulleyJoint->GetReactionForce(inv);

    return QPointF(rf.x, rf.y);
}

float Box2DPulleyJoint::reactionTorque(float inv)
{
    return mPulleyJoint->GetReactionTorque(inv);
}

float Box2DPulleyJoint::getLengthA()
{
    if (mPulleyJoint)
        return mPulleyJoint->GetLengthA() * scaleRatio;
    return mPulleyJointDef.lengthA;
}

float Box2DPulleyJoint::getLengthB()
{
    if (mPulleyJoint)
        return mPulleyJoint->GetLengthB() * scaleRatio;
    return mPulleyJointDef.lengthB;
}

void Box2DPulleyJoint::createJoint()
{
    mPulleyJointDef.Initialize(bodyA()->body(), bodyB()->body(),
	mPulleyJointDef.groundAnchorA,mPulleyJointDef.groundAnchorB,
	bodyA()->body()->GetWorldCenter(), bodyB()->body()->GetWorldCenter(),
	mPulleyJointDef.ratio);
    mPulleyJointDef.collideConnected = collideConnected();

    mPulleyJoint = static_cast<b2PulleyJoint*>(world()->CreateJoint(&mPulleyJointDef));
    mInitializePending = false;
}

void Box2DPulleyJoint::nullifyJoint()
{
    mPulleyJoint = 0;
}

void Box2DPulleyJoint::cleanup(b2World *world)
{
    if (mPulleyJoint && bodyA() && bodyB()) {
        mPulleyJoint->SetUserData(0);
        world->DestroyJoint(mPulleyJoint);
        mPulleyJoint = 0;
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/TestHarness.h"
#include "MockPrinter.h"
#include "CircularBuffer.h"

TEST_GROUP(CircularBuffer)
{ CircularBuffer* buffer;

void setup()
{
	buffer = new CircularBuffer();
}
void teardown()
{
	delete buffer;
}

void fillTheQueue(int seed, int howMany)
{
	for (int i = 0; i < howMany; i++)
	buffer->Put(seed + i);
}
void removeFromQueue(int howMany)
{
	for (int i = 0; i < howMany; i++)
	buffer->Get();
}
};

TEST(CircularBuffer, EmptyAfterCreation)
{
	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, NotEmpty)
{
	buffer->Put(10046);
	CHECK(!buffer->IsEmpty());
}

TEST(CircularBuffer, NotEmptyThenEmpty)
{
	buffer->Put(4567);
	CHECK(!buffer->IsEmpty());
	buffer->Get();
	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, GetPutOneValue)
{
	buffer->Put(4567);
	LONGS_EQUAL(4567, buffer->Get());
}

TEST(CircularBuffer, GetPutAFew)
{
	buffer->Put(1);
	buffer->Put(2);
	buffer->Put(3);
	LONGS_EQUAL(1, buffer->Get());
	LONGS_EQUAL(2, buffer->Get());
	LONGS_EQUAL(3, buffer->Get());
}

TEST(CircularBuffer, Capacity)
{
	CircularBuffer b(2);
	LONGS_EQUAL(2, b.Capacity());
}

TEST(CircularBuffer, IsFull)
{
	fillTheQueue(0, buffer->Capacity());
	CHECK(buffer->IsFull());
}

TEST(CircularBuffer, EmptyToFullToEmpty)
{
	fillTheQueue(100, buffer->Capacity());

	CHECK(buffer->IsFull());

	removeFromQueue(buffer->Capacity());

	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, WrapAround)
{
	fillTheQueue(100, buffer->Capacity());

	CHECK(buffer->IsFull());
	LONGS_EQUAL(100, buffer->Get());
	CHECK(!buffer->IsFull());
	buffer->Put(1000);
	CHECK(buffer->IsFull());

	removeFromQueue(buffer->Capacity() - 1);

	LONGS_EQUAL(1000, buffer->Get());
	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, PutToFull)
{
	int capacity = buffer->Capacity();
	fillTheQueue(900, capacity);
	buffer->Put(9999);

	for (int i = 0; i < buffer->Capacity() - 1; i++)
		LONGS_EQUAL(i+900+1, buffer->Get());

	LONGS_EQUAL(9999, buffer->Get());
	CHECK(buffer->IsEmpty());
}

//Sometime people ask what tests the tests.
//Do you know the answer

TEST(CircularBuffer, GetFromEmpty)
{
	LONGS_EQUAL(-1, buffer->Get());
	CHECK(buffer->IsEmpty());
}

/*
 * the next tests demonstrate using a mock object for
 * capturing output
 *
 */

TEST(CircularBuffer, PrintEmpty)
{
	MockPrinter mock;
	Printer* p = &mock;

	buffer->Print(p);
	CHECK_EQUAL("Circular buffer content:\n<>\n",
			mock.getOutput());
}

TEST(CircularBuffer, PrintAfterOnePut)
{
	MockPrinter mock;

	buffer->Put(1);
	buffer->Print(&mock);
	CHECK_EQUAL("Circular buffer content:\n<1>\n",
			mock.getOutput());
}

TEST(CircularBuffer, PrintNotYetWrappedOrFull)
{
	MockPrinter mock;

	buffer->Put(1);
	buffer->Put(2);
	buffer->Put(3);
	buffer->Print(&mock);
	CHECK_EQUAL("Circular buffer content:\n<1, 2, 3>\n",
			mock.getOutput());
}

TEST(CircularBuffer, PrintNotYetWrappedAndIsFull)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<200, 201, 202, 203, 204>\n";

	CHECK_EQUAL(expected, mock.getOutput());
}

TEST(CircularBuffer, PrintWrappedAndIsFullOldestToNewest)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	buffer->Get();
	buffer->Put(999);

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<201, 202, 203, 204, 999>\n";

	CHECK_EQUAL(expected, mock.getOutput());
}

TEST(CircularBuffer, PrintWrappedAndFullOverwriteOldest)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	buffer->Put(9999);

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<201, 202, 203, 204, 9999>\n";

	CHECK_EQUAL(expected, mock.getOutput());
}

TEST(CircularBuffer, PrintBoundary)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	removeFromQueue(buffer->Capacity() - 2);
	buffer->Put(888);
	fillTheQueue(300, buffer->Capacity() - 1);

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<888, 300, 301, 302, 303>\n";

	CHECK_EQUAL(expected, mock.getOutput());
}

TEST(CircularBuffer, FillEmptyThenPrint)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	removeFromQueue(buffer->Capacity());
	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<>\n";

	CHECK_EQUAL(expected, mock.getOutput());
}
<commit_msg>Fixed CircularBuffer test for the new CHECK_EQUAL<commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/TestHarness.h"
#include "MockPrinter.h"
#include "CircularBuffer.h"

TEST_GROUP(CircularBuffer)
{ CircularBuffer* buffer;

void setup()
{
	buffer = new CircularBuffer();
}
void teardown()
{
	delete buffer;
}

void fillTheQueue(int seed, int howMany)
{
	for (int i = 0; i < howMany; i++)
	buffer->Put(seed + i);
}
void removeFromQueue(int howMany)
{
	for (int i = 0; i < howMany; i++)
	buffer->Get();
}
};

TEST(CircularBuffer, EmptyAfterCreation)
{
	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, NotEmpty)
{
	buffer->Put(10046);
	CHECK(!buffer->IsEmpty());
}

TEST(CircularBuffer, NotEmptyThenEmpty)
{
	buffer->Put(4567);
	CHECK(!buffer->IsEmpty());
	buffer->Get();
	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, GetPutOneValue)
{
	buffer->Put(4567);
	LONGS_EQUAL(4567, buffer->Get());
}

TEST(CircularBuffer, GetPutAFew)
{
	buffer->Put(1);
	buffer->Put(2);
	buffer->Put(3);
	LONGS_EQUAL(1, buffer->Get());
	LONGS_EQUAL(2, buffer->Get());
	LONGS_EQUAL(3, buffer->Get());
}

TEST(CircularBuffer, Capacity)
{
	CircularBuffer b(2);
	LONGS_EQUAL(2, b.Capacity());
}

TEST(CircularBuffer, IsFull)
{
	fillTheQueue(0, buffer->Capacity());
	CHECK(buffer->IsFull());
}

TEST(CircularBuffer, EmptyToFullToEmpty)
{
	fillTheQueue(100, buffer->Capacity());

	CHECK(buffer->IsFull());

	removeFromQueue(buffer->Capacity());

	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, WrapAround)
{
	fillTheQueue(100, buffer->Capacity());

	CHECK(buffer->IsFull());
	LONGS_EQUAL(100, buffer->Get());
	CHECK(!buffer->IsFull());
	buffer->Put(1000);
	CHECK(buffer->IsFull());

	removeFromQueue(buffer->Capacity() - 1);

	LONGS_EQUAL(1000, buffer->Get());
	CHECK(buffer->IsEmpty());
}

TEST(CircularBuffer, PutToFull)
{
	int capacity = buffer->Capacity();
	fillTheQueue(900, capacity);
	buffer->Put(9999);

	for (int i = 0; i < buffer->Capacity() - 1; i++)
		LONGS_EQUAL(i+900+1, buffer->Get());

	LONGS_EQUAL(9999, buffer->Get());
	CHECK(buffer->IsEmpty());
}

//Sometime people ask what tests the tests.
//Do you know the answer

TEST(CircularBuffer, GetFromEmpty)
{
	LONGS_EQUAL(-1, buffer->Get());
	CHECK(buffer->IsEmpty());
}

/*
 * the next tests demonstrate using a mock object for
 * capturing output
 *
 */

TEST(CircularBuffer, PrintEmpty)
{
	MockPrinter mock;
	Printer* p = &mock;

	buffer->Print(p);
	STRCMP_EQUAL("Circular buffer content:\n<>\n",
			mock.getOutput().c_str());
}

TEST(CircularBuffer, PrintAfterOnePut)
{
	MockPrinter mock;

	buffer->Put(1);
	buffer->Print(&mock);
	STRCMP_EQUAL("Circular buffer content:\n<1>\n",
			mock.getOutput().c_str());
}

TEST(CircularBuffer, PrintNotYetWrappedOrFull)
{
	MockPrinter mock;

	buffer->Put(1);
	buffer->Put(2);
	buffer->Put(3);
	buffer->Print(&mock);
	STRCMP_EQUAL("Circular buffer content:\n<1, 2, 3>\n",
			mock.getOutput().c_str());
}

TEST(CircularBuffer, PrintNotYetWrappedAndIsFull)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<200, 201, 202, 203, 204>\n";

	STRCMP_EQUAL(expected, mock.getOutput().c_str());
}

TEST(CircularBuffer, PrintWrappedAndIsFullOldestToNewest)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	buffer->Get();
	buffer->Put(999);

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<201, 202, 203, 204, 999>\n";

	STRCMP_EQUAL(expected, mock.getOutput().c_str());
}

TEST(CircularBuffer, PrintWrappedAndFullOverwriteOldest)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	buffer->Put(9999);

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<201, 202, 203, 204, 9999>\n";

	STRCMP_EQUAL(expected, mock.getOutput().c_str());
}

TEST(CircularBuffer, PrintBoundary)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	removeFromQueue(buffer->Capacity() - 2);
	buffer->Put(888);
	fillTheQueue(300, buffer->Capacity() - 1);

	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<888, 300, 301, 302, 303>\n";

	STRCMP_EQUAL(expected, mock.getOutput().c_str());
}

TEST(CircularBuffer, FillEmptyThenPrint)
{
	MockPrinter mock;

	fillTheQueue(200, buffer->Capacity());
	removeFromQueue(buffer->Capacity());
	buffer->Print(&mock);
	const char* expected = "Circular buffer content:\n"
		"<>\n";

	STRCMP_EQUAL(expected, mock.getOutput().c_str());
}
<|endoftext|>


<commit_before>

- start up MinVR with a config file specified on command line
- display some simple opengl graphics

<commit_msg>Delete ExampleApp.cpp<commit_after><|endoftext|>


<commit_before>#include "ConstBuffer.h"
#include "DirectX.h"

using namespace Rendering::Buffer;

void ConstBuffer::Initialize(Device::DirectX& dx, uint size)
{
	assert(_base.GetBuffer().IsCanUse() == false);
	_size = size;

	D3D11_BUFFER_DESC desc;
	desc.Usage					= D3D11_USAGE_DEFAULT;
	desc.ByteWidth				= size;
	desc.BindFlags				= D3D11_BIND_CONSTANT_BUFFER;
	desc.CPUAccessFlags			= 0;
	desc.MiscFlags				= 0;
	desc.StructureByteStride	= 0;

	_base.SetBuffer(dx.CreateBuffer(desc, nullptr));
}

void ConstBuffer::UpdateSubResource(Device::DirectX& dx, const void* data)
{
	_base.UpdateSubResource(dx, &data);
}
<commit_msg>ConstBuffer - UpdateSubResource할때 data의 주소를 넘겨줘버리던 문제 수정 -_-..<commit_after>#include "ConstBuffer.h"
#include "DirectX.h"

using namespace Rendering::Buffer;

void ConstBuffer::Initialize(Device::DirectX& dx, uint size)
{
	assert(_base.GetBuffer().IsCanUse() == false);
	_size = size;

	D3D11_BUFFER_DESC desc;
	desc.Usage					= D3D11_USAGE_DEFAULT;
	desc.ByteWidth				= size;
	desc.BindFlags				= D3D11_BIND_CONSTANT_BUFFER;
	desc.CPUAccessFlags			= 0;
	desc.MiscFlags				= 0;
	desc.StructureByteStride	= 0;

	_base.SetBuffer(dx.CreateBuffer(desc, nullptr));
}

void ConstBuffer::UpdateSubResource(Device::DirectX& dx, const void* data)
{
	_base.UpdateSubResource(dx, data);
}
<|endoftext|>


<commit_before>#include "LightManager.h"

#include "VertexShader.h"
#include "PixelShader.h"
#include "GeometryShader.h"

#include "ShadowManager.h"

#include <type_traits>

using namespace Core;
using namespace Rendering;
using namespace Rendering::Shader;
using namespace Rendering::Buffer;
using namespace Rendering::View;
using namespace Rendering::Manager;
using namespace Rendering::Light;
using namespace Rendering::Light::Buffer;
using namespace Rendering::Shadow;

void LightManager::Initialize(Device::DirectX& dx)
{
	GetBuffer<DirectionalLight>().Initialize(dx);
	GetBuffer<PointLight>().Initialize(dx);
	GetBuffer<SpotLight>().Initialize(dx);
}

void LightManager::DeleteAll()
{
	GetBuffer<SpotLight>().DeleteAll();
	GetPool<SpotLight>().DeleteAll();
	GetDirtyParamLights<SpotLight>().clear();
	GetDirtyTransformLights<SpotLight>().clear();

	GetBuffer<PointLight>().DeleteAll();
	GetPool<PointLight>().DeleteAll();
	GetDirtyParamLights<PointLight>().clear();
	GetDirtyTransformLights<PointLight>().clear();

	GetBuffer<DirectionalLight>().DeleteAll();
	GetPool<DirectionalLight>().DeleteAll();
	GetDirtyParamLights<DirectionalLight>().clear();
	GetDirtyTransformLights<DirectionalLight>().clear();

	GetLightDatas<SpotLight>().reupdateMinIndex			= 0;
	GetLightDatas<PointLight>().reupdateMinIndex		= 0;
	GetLightDatas<DirectionalLight>().reupdateMinIndex	= 0;
}

uint LightManager::GetPackedLightCount() const
{
	uint spotLightCount			= GetLightCount<SpotLight>()		& 0x7FF;
	uint pointLightCount		= GetLightCount<PointLight>()		& 0x7FF;
	uint directionalLightCount	= GetLightCount<DirectionalLight>()	& 0x3FF;

	return (pointLightCount << 21) | (spotLightCount << 10) | directionalLightCount;
}

void LightManager::UpdateTransformBuffer(const Core::TransformPool& transformPool)
{
	GetBuffer<SpotLight>().UpdateTransformBuffer(GetDirtyTransformLights<SpotLight>(), transformPool, GetPool<SpotLight>().GetIndexer());
	GetBuffer<PointLight>().UpdateTransformBuffer(GetDirtyTransformLights<PointLight>(), transformPool, GetPool<PointLight>().GetIndexer());
	GetBuffer<DirectionalLight>().UpdateTransformBuffer(GetDirtyTransformLights<DirectionalLight>(), transformPool, GetPool<DirectionalLight>().GetIndexer());
}

void LightManager::UpdateParamBuffer(
	const ShadowManager& shadowMgr,
	const Core::ObjectID::IndexHashMap& shaftIndexer)
{
	GetBuffer<DirectionalLight>().
		UpdateLightCommonBuffer(
			GetDirtyParamLights<DirectionalLight>(),
			RequiredIndexer(shadowMgr.GetIndexer<DirectionalLightShadow>(), shaftIndexer),
			GetPool<DirectionalLight>().GetIndexer()
		);

	GetBuffer<PointLight>().
		UpdateLightCommonBuffer(
			GetDirtyParamLights<PointLight>(),
			RequiredIndexer(shadowMgr.GetIndexer<PointLightShadow>(), shaftIndexer),
			GetPool<PointLight>().GetIndexer()
		);

	GetBuffer<SpotLight>().
		UpdateLightCommonBuffer(
			GetDirtyParamLights<SpotLight>(),
			RequiredIndexer(shadowMgr.GetIndexer<SpotLightShadow>(), shaftIndexer),
			GetPool<SpotLight>().GetIndexer()
		);
}

void LightManager::UpdateSRBuffer(Device::DirectX& dx)
{
	GetBuffer<DirectionalLight>().UpdateSRBuffer(dx);
	GetBuffer<PointLight>().UpdateSRBuffer(dx);
	GetBuffer<SpotLight>().UpdateSRBuffer(dx);
}

void LightManager::CheckDirtyLights(const Core::TransformPool& transformPool)
{
	auto UpdateDirtyLight = [&transformPool](auto& lightDatas)
	{
		auto& pool = lightDatas.pool;
		auto& dirtyParamLights = lightDatas.dirtyParamLights;
		auto& dirtyTFLights = lightDatas.dirtyTransformLights;

		uint size = pool.GetSize();
		for (uint i = 0; i < size; ++i)
		{
			auto& light = pool.Get(i);

			if (i < lightDatas.reupdateMinIndex)
			{
				if (light.GetBase().GetDirty())
					dirtyParamLights.push_back(&light);

				uint objID = light.GetObjectID().Literal();
				auto transform = transformPool.Find(objID);
				if (transform->GetDirty())
					dirtyTFLights.push_back(&light);
			}
			else
			{
				dirtyParamLights.push_back(&light);
				dirtyTFLights.push_back(&light);
			}
		}

		lightDatas.reupdateMinIndex = size;
	};

	UpdateDirtyLight(GetLightDatas<DirectionalLight>());
	UpdateDirtyLight(GetLightDatas<PointLight>());
	UpdateDirtyLight(GetLightDatas<SpotLight>());
}

void LightManager::ClearDirty()
{
	auto UpdateDirtyLight = [](auto& dirtyLights)
	{
		for (auto light : dirtyLights)
			light->GetBase().SetDirty(false);
	};

	UpdateDirtyLight(GetDirtyParamLights<DirectionalLight>());
	UpdateDirtyLight(GetDirtyParamLights<PointLight>());
	UpdateDirtyLight(GetDirtyParamLights<SpotLight>());

	UpdateDirtyLight(GetDirtyTransformLights<DirectionalLight>());
	UpdateDirtyLight(GetDirtyTransformLights<PointLight>());
	UpdateDirtyLight(GetDirtyTransformLights<SpotLight>());
}

void LightManager::BindResources(Device::DirectX& dx, bool bindVS, bool bindGS, bool bindPS)
{
	auto Bind = [&dx, bindVS, bindGS, bindPS](
		TextureBindIndex bind, ShaderResourceBuffer& srb)
	{
		if (bindVS)	VertexShader::BindShaderResourceView(dx, bind, srb.GetShaderResourceView());
		if (bindGS)	GeometryShader::BindShaderResourceView(dx, bind, srb.GetShaderResourceView());
		if (bindPS)	PixelShader::BindShaderResourceView(dx, bind, srb.GetShaderResourceView());
	};

	auto& plBuffer = GetBuffer<PointLight>();
	{
		Bind(TextureBindIndex::PointLightRadiusWithCenter,		plBuffer.GetTransformSRBuffer());
		Bind(TextureBindIndex::PointLightColor,					plBuffer.GetColorSRBuffer());
		Bind(TextureBindIndex::PointLightOptionalParamIndex,	plBuffer.GetOptionalParamIndexSRBuffer());
	}

	auto& dlBuffer = GetBuffer<DirectionalLight>();
	{
		Bind(TextureBindIndex::DirectionalLightDirXY,				dlBuffer.GetTransformSRBuffer());
		Bind(TextureBindIndex::DirectionalLightColor,				dlBuffer.GetColorSRBuffer());
		Bind(TextureBindIndex::DirectionalLightOptionalParamIndex,	dlBuffer.GetOptionalParamIndexSRBuffer());
	}

	auto& slBuffer = GetBuffer<SpotLight>();
	{
		Bind(TextureBindIndex::SpotLightRadiusWithCenter,			slBuffer.GetTransformSRBuffer());
		Bind(TextureBindIndex::SpotLightColor,						slBuffer.GetColorSRBuffer());
		Bind(TextureBindIndex::SpotLightOptionalParamIndex,			slBuffer.GetOptionalParamIndexSRBuffer());
		Bind(TextureBindIndex::SpotLightParam,						slBuffer.GetParamSRBuffer());
	}
}

void LightManager::UnbindResources(Device::DirectX& dx, bool bindVS, bool bindGS, bool bindPS) const
{
	auto Unbind = [&dx, bindVS, bindGS, bindPS](TextureBindIndex bind)
	{
		if(bindVS) VertexShader::UnBindShaderResourceView(dx, bind);
		if(bindPS) PixelShader::UnBindShaderResourceView(dx, bind);
		if(bindGS) GeometryShader::UnBindShaderResourceView(dx, bind);
	};

	Unbind(TextureBindIndex::PointLightRadiusWithCenter);
	Unbind(TextureBindIndex::PointLightColor);
	Unbind(TextureBindIndex::PointLightOptionalParamIndex);

	Unbind(TextureBindIndex::DirectionalLightDirXY);
	Unbind(TextureBindIndex::DirectionalLightColor);
	Unbind(TextureBindIndex::DirectionalLightOptionalParamIndex);

	Unbind(TextureBindIndex::SpotLightRadiusWithCenter);
	Unbind(TextureBindIndex::SpotLightColor);
	Unbind(TextureBindIndex::SpotLightOptionalParamIndex);
	Unbind(TextureBindIndex::SpotLightParam);
}
<commit_msg>LightManager.cpp - reupdateMinIndex 제거<commit_after>#include "LightManager.h"

#include "VertexShader.h"
#include "PixelShader.h"
#include "GeometryShader.h"

#include "ShadowManager.h"

#include <type_traits>

using namespace Core;
using namespace Rendering;
using namespace Rendering::Shader;
using namespace Rendering::Buffer;
using namespace Rendering::View;
using namespace Rendering::Manager;
using namespace Rendering::Light;
using namespace Rendering::Light::Buffer;
using namespace Rendering::Shadow;

void LightManager::Initialize(Device::DirectX& dx)
{
	GetBuffer<DirectionalLight>().Initialize(dx);
	GetBuffer<PointLight>().Initialize(dx);
	GetBuffer<SpotLight>().Initialize(dx);
}

void LightManager::DeleteAll()
{
	GetBuffer<SpotLight>().DeleteAll();
	GetPool<SpotLight>().DeleteAll();
	GetDirtyParamLights<SpotLight>().clear();
	GetDirtyTransformLights<SpotLight>().clear();

	GetBuffer<PointLight>().DeleteAll();
	GetPool<PointLight>().DeleteAll();
	GetDirtyParamLights<PointLight>().clear();
	GetDirtyTransformLights<PointLight>().clear();

	GetBuffer<DirectionalLight>().DeleteAll();
	GetPool<DirectionalLight>().DeleteAll();
	GetDirtyParamLights<DirectionalLight>().clear();
	GetDirtyTransformLights<DirectionalLight>().clear();
}

uint LightManager::GetPackedLightCount() const
{
	uint spotLightCount			= GetLightCount<SpotLight>()		& 0x7FF;
	uint pointLightCount		= GetLightCount<PointLight>()		& 0x7FF;
	uint directionalLightCount	= GetLightCount<DirectionalLight>()	& 0x3FF;

	return (pointLightCount << 21) | (spotLightCount << 10) | directionalLightCount;
}

void LightManager::UpdateTransformBuffer(const Core::TransformPool& transformPool)
{
	GetBuffer<SpotLight>().UpdateTransformBuffer(GetDirtyTransformLights<SpotLight>(), transformPool, GetPool<SpotLight>().GetIndexer());
	GetBuffer<PointLight>().UpdateTransformBuffer(GetDirtyTransformLights<PointLight>(), transformPool, GetPool<PointLight>().GetIndexer());
	GetBuffer<DirectionalLight>().UpdateTransformBuffer(GetDirtyTransformLights<DirectionalLight>(), transformPool, GetPool<DirectionalLight>().GetIndexer());
}

void LightManager::UpdateParamBuffer(
	const ShadowManager& shadowMgr,
	const Core::ObjectID::IndexHashMap& shaftIndexer)
{
	GetBuffer<DirectionalLight>().
		UpdateLightCommonBuffer(
			GetDirtyParamLights<DirectionalLight>(),
			RequiredIndexer(shadowMgr.GetIndexer<DirectionalLightShadow>(), shaftIndexer),
			GetPool<DirectionalLight>().GetIndexer()
		);

	GetBuffer<PointLight>().
		UpdateLightCommonBuffer(
			GetDirtyParamLights<PointLight>(),
			RequiredIndexer(shadowMgr.GetIndexer<PointLightShadow>(), shaftIndexer),
			GetPool<PointLight>().GetIndexer()
		);

	GetBuffer<SpotLight>().
		UpdateLightCommonBuffer(
			GetDirtyParamLights<SpotLight>(),
			RequiredIndexer(shadowMgr.GetIndexer<SpotLightShadow>(), shaftIndexer),
			GetPool<SpotLight>().GetIndexer()
		);
}

void LightManager::UpdateSRBuffer(Device::DirectX& dx)
{
	GetBuffer<DirectionalLight>().UpdateSRBuffer(dx);
	GetBuffer<PointLight>().UpdateSRBuffer(dx);
	GetBuffer<SpotLight>().UpdateSRBuffer(dx);
}

void LightManager::CheckDirtyLights(const Core::TransformPool& transformPool)
{
	auto UpdateDirtyLight = [&transformPool](auto& lightDatas)
	{
		auto& pool = lightDatas.pool;
		auto& dirtyParamLights = lightDatas.dirtyParamLights;
		auto& dirtyTFLights = lightDatas.dirtyTransformLights;

		uint size = pool.GetSize();
		for (uint i = 0; i < size; ++i)
		{
			auto& light = pool.Get(i);

			if (light.GetBase().GetDirty())
				dirtyParamLights.push_back(&light);

			uint objID = light.GetObjectID().Literal();
			auto transform = transformPool.Find(objID);
			if (transform->GetDirty())
				dirtyTFLights.push_back(&light);
		}
	};

	UpdateDirtyLight(GetLightDatas<DirectionalLight>());
	UpdateDirtyLight(GetLightDatas<PointLight>());
	UpdateDirtyLight(GetLightDatas<SpotLight>());
}

void LightManager::ClearDirty()
{
	auto UpdateDirtyLight = [](auto& dirtyLights)
	{
		for (auto light : dirtyLights)
			light->GetBase().SetDirty(false);
	};

	UpdateDirtyLight(GetDirtyParamLights<DirectionalLight>());
	UpdateDirtyLight(GetDirtyParamLights<PointLight>());
	UpdateDirtyLight(GetDirtyParamLights<SpotLight>());

	UpdateDirtyLight(GetDirtyTransformLights<DirectionalLight>());
	UpdateDirtyLight(GetDirtyTransformLights<PointLight>());
	UpdateDirtyLight(GetDirtyTransformLights<SpotLight>());
}

void LightManager::BindResources(Device::DirectX& dx, bool bindVS, bool bindGS, bool bindPS)
{
	auto Bind = [&dx, bindVS, bindGS, bindPS](
		TextureBindIndex bind, ShaderResourceBuffer& srb)
	{
		if (bindVS)	VertexShader::BindShaderResourceView(dx, bind, srb.GetShaderResourceView());
		if (bindGS)	GeometryShader::BindShaderResourceView(dx, bind, srb.GetShaderResourceView());
		if (bindPS)	PixelShader::BindShaderResourceView(dx, bind, srb.GetShaderResourceView());
	};

	auto& plBuffer = GetBuffer<PointLight>();
	{
		Bind(TextureBindIndex::PointLightRadiusWithCenter,		plBuffer.GetTransformSRBuffer());
		Bind(TextureBindIndex::PointLightColor,					plBuffer.GetColorSRBuffer());
		Bind(TextureBindIndex::PointLightOptionalParamIndex,	plBuffer.GetOptionalParamIndexSRBuffer());
	}

	auto& dlBuffer = GetBuffer<DirectionalLight>();
	{
		Bind(TextureBindIndex::DirectionalLightDirXY,				dlBuffer.GetTransformSRBuffer());
		Bind(TextureBindIndex::DirectionalLightColor,				dlBuffer.GetColorSRBuffer());
		Bind(TextureBindIndex::DirectionalLightOptionalParamIndex,	dlBuffer.GetOptionalParamIndexSRBuffer());
	}

	auto& slBuffer = GetBuffer<SpotLight>();
	{
		Bind(TextureBindIndex::SpotLightRadiusWithCenter,			slBuffer.GetTransformSRBuffer());
		Bind(TextureBindIndex::SpotLightColor,						slBuffer.GetColorSRBuffer());
		Bind(TextureBindIndex::SpotLightOptionalParamIndex,			slBuffer.GetOptionalParamIndexSRBuffer());
		Bind(TextureBindIndex::SpotLightParam,						slBuffer.GetParamSRBuffer());
	}
}

void LightManager::UnbindResources(Device::DirectX& dx, bool bindVS, bool bindGS, bool bindPS) const
{
	auto Unbind = [&dx, bindVS, bindGS, bindPS](TextureBindIndex bind)
	{
		if(bindVS) VertexShader::UnBindShaderResourceView(dx, bind);
		if(bindPS) PixelShader::UnBindShaderResourceView(dx, bind);
		if(bindGS) GeometryShader::UnBindShaderResourceView(dx, bind);
	};

	Unbind(TextureBindIndex::PointLightRadiusWithCenter);
	Unbind(TextureBindIndex::PointLightColor);
	Unbind(TextureBindIndex::PointLightOptionalParamIndex);

	Unbind(TextureBindIndex::DirectionalLightDirXY);
	Unbind(TextureBindIndex::DirectionalLightColor);
	Unbind(TextureBindIndex::DirectionalLightOptionalParamIndex);

	Unbind(TextureBindIndex::SpotLightRadiusWithCenter);
	Unbind(TextureBindIndex::SpotLightColor);
	Unbind(TextureBindIndex::SpotLightOptionalParamIndex);
	Unbind(TextureBindIndex::SpotLightParam);
}
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          test.cpp
* Purpose:       Implementation for wxfiletool cpp unit testing
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id: test.cpp 589 2009-04-09 13:43:53Z antonvw $
* Created:       za 17 jan 2009 11:51:20 CET
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <TestCaller.h>
#include "test.h"

void wxExReportAppTestFixture::setUp()
{
  m_ListView = new wxExListViewFile(wxTheApp->GetTopWindow(), wxExListViewFile::LIST_PROCESS);
  m_Dir = new wxExDirWithReport(m_ListView, "./");
  m_Process = new wxExProcessWithListView(m_ListView, "wc test.h");
  m_STC = new wxExSTCWithFrame(wxTheApp->GetTopWindow(), wxExFileName("test.h"));
}

void wxExReportAppTestFixture::testConstructors()
{
}

void wxExReportAppTestFixture::testMethods()
{
  // test wxExDirWithReport
  CPPUNIT_ASSERT(m_Dir->FindFiles());

  // test wxExListViewFile
  CPPUNIT_ASSERT(m_ListView->FileOpen(wxExFileName("test.prj")));
  CPPUNIT_ASSERT(m_ListView->ItemFromText("test1\ntest2\n"));

  // test wxExProcessWithListView
  CPPUNIT_ASSERT(m_Process->Run());
  CPPUNIT_ASSERT(m_Process->Kill() == wxKILL_OK);

  // test wxExSTCWithFrame
  CPPUNIT_ASSERT(m_STC->GetFileName().GetFullName() == "test.h");
}

void wxExReportAppTestFixture::tearDown()
{
}

wxExReportTestSuite::wxExReportTestSuite()
  : CppUnit::TestSuite("wxfiletool test suite")
{
  addTest(new CppUnit::TestCaller<wxExReportAppTestFixture>(
    "testConstructors",
    &wxExReportAppTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<wxExReportAppTestFixture>(
    "testMethods",
    &wxExReportAppTestFixture::testMethods));
}

<commit_msg>changed names<commit_after>/******************************************************************************\
* File:          test.cpp
* Purpose:       Implementation for wxextension report cpp unit testing
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id: test.cpp 589 2009-04-09 13:43:53Z antonvw $
* Created:       za 17 jan 2009 11:51:20 CET
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <TestCaller.h>
#include "test.h"

void wxExReportAppTestFixture::setUp()
{
  m_ListView = new wxExListViewFile(wxTheApp->GetTopWindow(), wxExListViewFile::LIST_PROCESS);
  m_Dir = new wxExDirWithReport(m_ListView, "./");
  m_Process = new wxExProcessWithListView(m_ListView, "wc test.h");
  m_STC = new wxExSTCWithFrame(wxTheApp->GetTopWindow(), wxExFileName("test.h"));
}

void wxExReportAppTestFixture::testConstructors()
{
}

void wxExReportAppTestFixture::testMethods()
{
  // test wxExDirWithReport
  CPPUNIT_ASSERT(m_Dir->FindFiles());

  // test wxExListViewFile
  CPPUNIT_ASSERT(m_ListView->FileOpen(wxExFileName("test.prj")));
  CPPUNIT_ASSERT(m_ListView->ItemFromText("test1\ntest2\n"));

  // test wxExProcessWithListView
  CPPUNIT_ASSERT(m_Process->Run());
  CPPUNIT_ASSERT(m_Process->Kill() == wxKILL_OK);

  // test wxExSTCWithFrame
  CPPUNIT_ASSERT(m_STC->GetFileName().GetFullName() == "test.h");
}

void wxExReportAppTestFixture::tearDown()
{
}

wxExReportTestSuite::wxExReportTestSuite()
  : CppUnit::TestSuite("wxexreport test suite")
{
  addTest(new CppUnit::TestCaller<wxExReportAppTestFixture>(
    "testConstructors",
    &wxExReportAppTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<wxExReportAppTestFixture>(
    "testMethods",
    &wxExReportAppTestFixture::testMethods));
}

<|endoftext|>


<commit_before>//===-- sanitizer_libc_test.cc --------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Tests for sanitizer_libc.h.
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <fstream>

#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_file.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_platform.h"
#include "gtest/gtest.h"

#if SANITIZER_WINDOWS
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
#endif
#if SANITIZER_POSIX
# include <sys/stat.h>
# include "sanitizer_common/sanitizer_posix.h"
#endif

using namespace __sanitizer;

// A regression test for internal_memmove() implementation.
TEST(SanitizerCommon, InternalMemmoveRegression) {
  char src[] = "Hello World";
  char *dest = src + 6;
  __sanitizer::internal_memmove(dest, src, 5);
  EXPECT_EQ(dest[0], src[0]);
  EXPECT_EQ(dest[4], src[4]);
}

TEST(SanitizerCommon, mem_is_zero) {
  size_t size = 128;
  char *x = new char[size];
  memset(x, 0, size);
  for (size_t pos = 0; pos < size; pos++) {
    x[pos] = 1;
    for (size_t beg = 0; beg < size; beg++) {
      for (size_t end = beg; end < size; end++) {
        // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
        if (beg <= pos && pos < end)
          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
        else
          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
      }
    }
    x[pos] = 0;
  }
  delete [] x;
}

struct stat_and_more {
  struct stat st;
  unsigned char z;
};

static void temp_file_name(char *buf, size_t bufsize, const char *prefix) {
#if SANITIZER_WINDOWS
  buf[0] = '\0';
  char tmp_dir[MAX_PATH];
  if (!::GetTempPathA(MAX_PATH, tmp_dir))
    return;
  // GetTempFileNameA needs a MAX_PATH buffer.
  char tmp_path[MAX_PATH];
  if (!::GetTempFileNameA(tmp_dir, prefix, 0, tmp_path))
    return;
  internal_strncpy(buf, tmp_path, bufsize);
#else
  const char *tmpdir = "/tmp";
#if SANITIZER_ANDROID
  // I don't know a way to query temp directory location on Android without
  // going through Java interfaces. The code below is not ideal, but should
  // work. May require "adb root", but it is needed for almost any use of ASan
  // on Android already.
  tmpdir = GetEnv("EXTERNAL_STORAGE");
#endif
  internal_snprintf(buf, bufsize, "%s/%sXXXXXX", tmpdir, prefix);
  ASSERT_TRUE(mkstemp(buf));
#endif
}

static void Unlink(const char *path) {
#if SANITIZER_WINDOWS
  // No sanitizer needs to delete a file on Windows yet. If we ever do, we can
  // add a portable wrapper and test it from here.
  ::DeleteFileA(&path[0]);
#else
  internal_unlink(path);
#endif
}

TEST(SanitizerCommon, FileOps) {
  const char *str1 = "qwerty";
  uptr len1 = internal_strlen(str1);
  const char *str2 = "zxcv";
  uptr len2 = internal_strlen(str2);

  char tmpfile[128];
  temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
  fd_t fd = OpenFile(tmpfile, WrOnly);
  ASSERT_NE(fd, kInvalidFd);
  ASSERT_FALSE(internal_iserror(internal_write(fd, "A", 1)));
  CloseFile(fd);

  fd = OpenFile(tmpfile, WrOnly);
  ASSERT_NE(fd, kInvalidFd);
  EXPECT_EQ(internal_lseek(fd, 0, SEEK_END), 0u);
  uptr bytes_written = 0;
  EXPECT_TRUE(WriteToFile(fd, str1, len1, &bytes_written));
  EXPECT_EQ(len1, bytes_written);
  EXPECT_TRUE(WriteToFile(fd, str2, len2, &bytes_written));
  EXPECT_EQ(len2, bytes_written);
  CloseFile(fd);

  EXPECT_TRUE(FileExists(tmpfile));

  fd = OpenFile(tmpfile, RdOnly);
  ASSERT_NE(fd, kInvalidFd);

#if SANITIZER_POSIX
  // The stat wrappers are posix-only.
  uptr fsize = internal_filesize(fd);
  EXPECT_EQ(len1 + len2, fsize);

  struct stat st1, st2, st3;
  EXPECT_EQ(0u, internal_stat(tmpfile, &st1));
  EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));
  EXPECT_EQ(0u, internal_fstat(fd, &st3));
  EXPECT_EQ(fsize, (uptr)st3.st_size);

  // Verify that internal_fstat does not write beyond the end of the supplied
  // buffer.
  struct stat_and_more sam;
  memset(&sam, 0xAB, sizeof(sam));
  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
  EXPECT_EQ(0xAB, sam.z);
  EXPECT_NE(0xAB, sam.st.st_size);
  EXPECT_NE(0, sam.st.st_size);
#endif

  char buf[64] = {};
  uptr bytes_read = 0;
  EXPECT_TRUE(ReadFromFile(fd, buf, len1, &bytes_read));
  EXPECT_EQ(len1, bytes_read);
  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
  EXPECT_EQ((char)0, buf[len1 + 1]);
  internal_memset(buf, 0, len1);
  EXPECT_TRUE(ReadFromFile(fd, buf, len2, &bytes_read));
  EXPECT_EQ(len2, bytes_read);
  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
  CloseFile(fd);

  Unlink(tmpfile);
}

class SanitizerCommonFileTest : public ::testing::TestWithParam<uptr> {
  void SetUp() override {
    data_.resize(GetParam());
    std::generate(data_.begin(), data_.end(), [] {
      return rand() % 256;  // NOLINT
    });

    temp_file_name(file_name_, sizeof(file_name_),
                   "sanitizer_common.ReadFile.tmp.");

    std::ofstream f(file_name_, std::ios::out | std::ios::binary);
    if (!data_.empty())
      f.write(data_.data(), data_.size());
  }

  void TearDown() override { Unlink(file_name_); }

 protected:
  char file_name_[256];
  std::vector<char> data_;
};

TEST_P(SanitizerCommonFileTest, ReadFileToBuffer) {
  char *buff;
  uptr size;
  uptr len;
  EXPECT_TRUE(ReadFileToBuffer(file_name_, &buff, &len, &size));
  EXPECT_EQ(data_, std::vector<char>(buff, buff + size));
  UnmapOrDie(buff, len);
}

TEST_P(SanitizerCommonFileTest, ReadFileToBufferHalf) {
  char *buff;
  uptr size;
  uptr len;
  data_.resize(data_.size() / 2);
  EXPECT_TRUE(ReadFileToBuffer(file_name_, &buff, &len, &size, data_.size()));
  EXPECT_EQ(data_, std::vector<char>(buff, buff + size));
  UnmapOrDie(buff, len);
}

TEST_P(SanitizerCommonFileTest, ReadFileToVector) {
  InternalMmapVector<char> buff;
  EXPECT_TRUE(ReadFileToVector(file_name_, &buff));
  EXPECT_EQ(data_, std::vector<char>(buff.begin(), buff.end()));
}

TEST_P(SanitizerCommonFileTest, ReadFileToVectorHalf) {
  InternalMmapVector<char> buff;
  data_.resize(data_.size() / 2);
  EXPECT_TRUE(ReadFileToVector(file_name_, &buff, data_.size()));
  EXPECT_EQ(data_, std::vector<char>(buff.begin(), buff.end()));
}

INSTANTIATE_TEST_CASE_P(FileSizes, SanitizerCommonFileTest,
                        ::testing::Values(0, 1, 7, 13, 32, 4096, 4097, 1048575,
                                          1048576, 1048577));

static const size_t kStrlcpyBufSize = 8;
void test_internal_strlcpy(char *dbuf, const char *sbuf) {
  uptr retval = 0;
  retval = internal_strlcpy(dbuf, sbuf, kStrlcpyBufSize);
  EXPECT_EQ(internal_strncmp(dbuf, sbuf, kStrlcpyBufSize - 1), 0);
  EXPECT_EQ(internal_strlen(dbuf),
            std::min(internal_strlen(sbuf), (uptr)(kStrlcpyBufSize - 1)));
  EXPECT_EQ(retval, internal_strlen(sbuf));

  // Test with shorter maxlen.
  uptr maxlen = 2;
  if (internal_strlen(sbuf) > maxlen) {
    retval = internal_strlcpy(dbuf, sbuf, maxlen);
    EXPECT_EQ(internal_strncmp(dbuf, sbuf, maxlen - 1), 0);
    EXPECT_EQ(internal_strlen(dbuf), maxlen - 1);
  }
}

TEST(SanitizerCommon, InternalStrFunctions) {
  const char *haystack = "haystack";
  EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
  EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
  EXPECT_EQ(0, internal_strchr(haystack, 'z'));
  EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));

  char dbuf[kStrlcpyBufSize] = {};
  const char *samesizestr = "1234567";
  const char *shortstr = "123";
  const char *longerstr = "123456789";

  // Test internal_strlcpy.
  internal_strlcpy(dbuf, shortstr, 0);
  EXPECT_EQ(dbuf[0], 0);
  EXPECT_EQ(dbuf[0], 0);
  test_internal_strlcpy(dbuf, samesizestr);
  test_internal_strlcpy(dbuf, shortstr);
  test_internal_strlcpy(dbuf, longerstr);

  // Test internal_strlcat.
  char dcatbuf[kStrlcpyBufSize] = {};
  uptr retval = 0;
  retval = internal_strlcat(dcatbuf, "aaa", 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)0);
  EXPECT_EQ(retval, (uptr)3);

  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
  EXPECT_EQ(internal_strcmp(dcatbuf, "123"), 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)3);
  EXPECT_EQ(retval, (uptr)3);

  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
  EXPECT_EQ(internal_strcmp(dcatbuf, "123123"), 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)6);
  EXPECT_EQ(retval, (uptr)6);

  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
  EXPECT_EQ(internal_strcmp(dcatbuf, "1231231"), 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)7);
  EXPECT_EQ(retval, (uptr)9);
}

// FIXME: File manipulations are not yet supported on Windows
#if SANITIZER_POSIX && !SANITIZER_MAC
TEST(SanitizerCommon, InternalMmapWithOffset) {
  char tmpfile[128];
  temp_file_name(tmpfile, sizeof(tmpfile),
                 "sanitizer_common.internalmmapwithoffset.tmp.");
  fd_t fd = OpenFile(tmpfile, RdWr);
  ASSERT_NE(fd, kInvalidFd);

  uptr page_size = GetPageSizeCached();
  uptr res = internal_ftruncate(fd, page_size * 2);
  ASSERT_FALSE(internal_iserror(res));

  res = internal_lseek(fd, page_size, SEEK_SET);
  ASSERT_FALSE(internal_iserror(res));

  res = internal_write(fd, "AB", 2);
  ASSERT_FALSE(internal_iserror(res));

  char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);
  ASSERT_NE(nullptr, p);

  ASSERT_EQ('A', p[0]);
  ASSERT_EQ('B', p[1]);

  CloseFile(fd);
  UnmapOrDie(p, page_size);
  internal_unlink(tmpfile);
}
#endif
<commit_msg>[sanitizer_common] Fix windows build caused by r334881<commit_after>//===-- sanitizer_libc_test.cc --------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Tests for sanitizer_libc.h.
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <fstream>

#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_file.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_platform.h"
#include "gtest/gtest.h"

#if SANITIZER_WINDOWS
#define NOMINMAX
#include <windows.h>
#undef NOMINMAX
#endif
#if SANITIZER_POSIX
# include <sys/stat.h>
# include "sanitizer_common/sanitizer_posix.h"
#endif

using namespace __sanitizer;

// A regression test for internal_memmove() implementation.
TEST(SanitizerCommon, InternalMemmoveRegression) {
  char src[] = "Hello World";
  char *dest = src + 6;
  __sanitizer::internal_memmove(dest, src, 5);
  EXPECT_EQ(dest[0], src[0]);
  EXPECT_EQ(dest[4], src[4]);
}

TEST(SanitizerCommon, mem_is_zero) {
  size_t size = 128;
  char *x = new char[size];
  memset(x, 0, size);
  for (size_t pos = 0; pos < size; pos++) {
    x[pos] = 1;
    for (size_t beg = 0; beg < size; beg++) {
      for (size_t end = beg; end < size; end++) {
        // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
        if (beg <= pos && pos < end)
          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
        else
          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
      }
    }
    x[pos] = 0;
  }
  delete [] x;
}

struct stat_and_more {
  struct stat st;
  unsigned char z;
};

static void temp_file_name(char *buf, size_t bufsize, const char *prefix) {
#if SANITIZER_WINDOWS
  buf[0] = '\0';
  char tmp_dir[MAX_PATH];
  if (!::GetTempPathA(MAX_PATH, tmp_dir))
    return;
  // GetTempFileNameA needs a MAX_PATH buffer.
  char tmp_path[MAX_PATH];
  if (!::GetTempFileNameA(tmp_dir, prefix, 0, tmp_path))
    return;
  internal_strncpy(buf, tmp_path, bufsize);
#else
  const char *tmpdir = "/tmp";
#if SANITIZER_ANDROID
  // I don't know a way to query temp directory location on Android without
  // going through Java interfaces. The code below is not ideal, but should
  // work. May require "adb root", but it is needed for almost any use of ASan
  // on Android already.
  tmpdir = GetEnv("EXTERNAL_STORAGE");
#endif
  internal_snprintf(buf, bufsize, "%s/%sXXXXXX", tmpdir, prefix);
  ASSERT_TRUE(mkstemp(buf));
#endif
}

static void Unlink(const char *path) {
#if SANITIZER_WINDOWS
  // No sanitizer needs to delete a file on Windows yet. If we ever do, we can
  // add a portable wrapper and test it from here.
  ::DeleteFileA(&path[0]);
#else
  internal_unlink(path);
#endif
}

TEST(SanitizerCommon, FileOps) {
  const char *str1 = "qwerty";
  uptr len1 = internal_strlen(str1);
  const char *str2 = "zxcv";
  uptr len2 = internal_strlen(str2);

  char tmpfile[128];
  temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
  fd_t fd = OpenFile(tmpfile, WrOnly);
  ASSERT_NE(fd, kInvalidFd);
  ASSERT_TRUE(WriteToFile(fd, "A", 1));
  CloseFile(fd);

  fd = OpenFile(tmpfile, WrOnly);
  ASSERT_NE(fd, kInvalidFd);
#if SANITIZER_POSIX
  EXPECT_EQ(internal_lseek(fd, 0, SEEK_END), 0u);
#endif
  uptr bytes_written = 0;
  EXPECT_TRUE(WriteToFile(fd, str1, len1, &bytes_written));
  EXPECT_EQ(len1, bytes_written);
  EXPECT_TRUE(WriteToFile(fd, str2, len2, &bytes_written));
  EXPECT_EQ(len2, bytes_written);
  CloseFile(fd);

  EXPECT_TRUE(FileExists(tmpfile));

  fd = OpenFile(tmpfile, RdOnly);
  ASSERT_NE(fd, kInvalidFd);

#if SANITIZER_POSIX
  // The stat wrappers are posix-only.
  uptr fsize = internal_filesize(fd);
  EXPECT_EQ(len1 + len2, fsize);

  struct stat st1, st2, st3;
  EXPECT_EQ(0u, internal_stat(tmpfile, &st1));
  EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));
  EXPECT_EQ(0u, internal_fstat(fd, &st3));
  EXPECT_EQ(fsize, (uptr)st3.st_size);

  // Verify that internal_fstat does not write beyond the end of the supplied
  // buffer.
  struct stat_and_more sam;
  memset(&sam, 0xAB, sizeof(sam));
  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
  EXPECT_EQ(0xAB, sam.z);
  EXPECT_NE(0xAB, sam.st.st_size);
  EXPECT_NE(0, sam.st.st_size);
#endif

  char buf[64] = {};
  uptr bytes_read = 0;
  EXPECT_TRUE(ReadFromFile(fd, buf, len1, &bytes_read));
  EXPECT_EQ(len1, bytes_read);
  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
  EXPECT_EQ((char)0, buf[len1 + 1]);
  internal_memset(buf, 0, len1);
  EXPECT_TRUE(ReadFromFile(fd, buf, len2, &bytes_read));
  EXPECT_EQ(len2, bytes_read);
  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
  CloseFile(fd);

  Unlink(tmpfile);
}

class SanitizerCommonFileTest : public ::testing::TestWithParam<uptr> {
  void SetUp() override {
    data_.resize(GetParam());
    std::generate(data_.begin(), data_.end(), [] {
      return rand() % 256;  // NOLINT
    });

    temp_file_name(file_name_, sizeof(file_name_),
                   "sanitizer_common.ReadFile.tmp.");

    std::ofstream f(file_name_, std::ios::out | std::ios::binary);
    if (!data_.empty())
      f.write(data_.data(), data_.size());
  }

  void TearDown() override { Unlink(file_name_); }

 protected:
  char file_name_[256];
  std::vector<char> data_;
};

TEST_P(SanitizerCommonFileTest, ReadFileToBuffer) {
  char *buff;
  uptr size;
  uptr len;
  EXPECT_TRUE(ReadFileToBuffer(file_name_, &buff, &len, &size));
  EXPECT_EQ(data_, std::vector<char>(buff, buff + size));
  UnmapOrDie(buff, len);
}

TEST_P(SanitizerCommonFileTest, ReadFileToBufferHalf) {
  char *buff;
  uptr size;
  uptr len;
  data_.resize(data_.size() / 2);
  EXPECT_TRUE(ReadFileToBuffer(file_name_, &buff, &len, &size, data_.size()));
  EXPECT_EQ(data_, std::vector<char>(buff, buff + size));
  UnmapOrDie(buff, len);
}

TEST_P(SanitizerCommonFileTest, ReadFileToVector) {
  InternalMmapVector<char> buff;
  EXPECT_TRUE(ReadFileToVector(file_name_, &buff));
  EXPECT_EQ(data_, std::vector<char>(buff.begin(), buff.end()));
}

TEST_P(SanitizerCommonFileTest, ReadFileToVectorHalf) {
  InternalMmapVector<char> buff;
  data_.resize(data_.size() / 2);
  EXPECT_TRUE(ReadFileToVector(file_name_, &buff, data_.size()));
  EXPECT_EQ(data_, std::vector<char>(buff.begin(), buff.end()));
}

INSTANTIATE_TEST_CASE_P(FileSizes, SanitizerCommonFileTest,
                        ::testing::Values(0, 1, 7, 13, 32, 4096, 4097, 1048575,
                                          1048576, 1048577));

static const size_t kStrlcpyBufSize = 8;
void test_internal_strlcpy(char *dbuf, const char *sbuf) {
  uptr retval = 0;
  retval = internal_strlcpy(dbuf, sbuf, kStrlcpyBufSize);
  EXPECT_EQ(internal_strncmp(dbuf, sbuf, kStrlcpyBufSize - 1), 0);
  EXPECT_EQ(internal_strlen(dbuf),
            std::min(internal_strlen(sbuf), (uptr)(kStrlcpyBufSize - 1)));
  EXPECT_EQ(retval, internal_strlen(sbuf));

  // Test with shorter maxlen.
  uptr maxlen = 2;
  if (internal_strlen(sbuf) > maxlen) {
    retval = internal_strlcpy(dbuf, sbuf, maxlen);
    EXPECT_EQ(internal_strncmp(dbuf, sbuf, maxlen - 1), 0);
    EXPECT_EQ(internal_strlen(dbuf), maxlen - 1);
  }
}

TEST(SanitizerCommon, InternalStrFunctions) {
  const char *haystack = "haystack";
  EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
  EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
  EXPECT_EQ(0, internal_strchr(haystack, 'z'));
  EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));

  char dbuf[kStrlcpyBufSize] = {};
  const char *samesizestr = "1234567";
  const char *shortstr = "123";
  const char *longerstr = "123456789";

  // Test internal_strlcpy.
  internal_strlcpy(dbuf, shortstr, 0);
  EXPECT_EQ(dbuf[0], 0);
  EXPECT_EQ(dbuf[0], 0);
  test_internal_strlcpy(dbuf, samesizestr);
  test_internal_strlcpy(dbuf, shortstr);
  test_internal_strlcpy(dbuf, longerstr);

  // Test internal_strlcat.
  char dcatbuf[kStrlcpyBufSize] = {};
  uptr retval = 0;
  retval = internal_strlcat(dcatbuf, "aaa", 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)0);
  EXPECT_EQ(retval, (uptr)3);

  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
  EXPECT_EQ(internal_strcmp(dcatbuf, "123"), 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)3);
  EXPECT_EQ(retval, (uptr)3);

  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
  EXPECT_EQ(internal_strcmp(dcatbuf, "123123"), 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)6);
  EXPECT_EQ(retval, (uptr)6);

  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
  EXPECT_EQ(internal_strcmp(dcatbuf, "1231231"), 0);
  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)7);
  EXPECT_EQ(retval, (uptr)9);
}

// FIXME: File manipulations are not yet supported on Windows
#if SANITIZER_POSIX && !SANITIZER_MAC
TEST(SanitizerCommon, InternalMmapWithOffset) {
  char tmpfile[128];
  temp_file_name(tmpfile, sizeof(tmpfile),
                 "sanitizer_common.internalmmapwithoffset.tmp.");
  fd_t fd = OpenFile(tmpfile, RdWr);
  ASSERT_NE(fd, kInvalidFd);

  uptr page_size = GetPageSizeCached();
  uptr res = internal_ftruncate(fd, page_size * 2);
  ASSERT_FALSE(internal_iserror(res));

  res = internal_lseek(fd, page_size, SEEK_SET);
  ASSERT_FALSE(internal_iserror(res));

  res = internal_write(fd, "AB", 2);
  ASSERT_FALSE(internal_iserror(res));

  char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);
  ASSERT_NE(nullptr, p);

  ASSERT_EQ('A', p[0]);
  ASSERT_EQ('B', p[1]);

  CloseFile(fd);
  UnmapOrDie(p, page_size);
  internal_unlink(tmpfile);
}
#endif
<|endoftext|>


<commit_before><commit_msg>fix const condition check<commit_after><|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2020 Ryo Suzuki
//	Copyright (c) 2016-2020 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include "OpenGL.hpp"
# include <Siv3D/EngineLog.hpp>

namespace s3d
{
	void CheckOpenGLError()
	{
		size_t limitter = 0;

		GLenum err;

		while ((err = glGetError()) != GL_NO_ERROR)
		{
			LOG_ERROR(U"OpenGL Error: 0x{:x}"_fmt(err));

			if (++limitter > 30)
			{
				LOG_ERROR(U"OpenGL error report interrupted.");
				break;
			}
		}
	}
}
<commit_msg>[Web] [Performance] Reduce calling glGetError on Release build<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2020 Ryo Suzuki
//	Copyright (c) 2016-2020 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# include "OpenGL.hpp"
# include <Siv3D/EngineLog.hpp>

namespace s3d
{
	void CheckOpenGLError()
	{
		if constexpr(SIV3D_BUILD(DEBUG))
		{
			size_t limitter = 0;

			GLenum err;

			while ((err = glGetError()) != GL_NO_ERROR)
			{
				LOG_ERROR(U"OpenGL Error: 0x{:x}"_fmt(err));

				if (++limitter > 30)
				{
					LOG_ERROR(U"OpenGL error report interrupted.");
					break;
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"

namespace caf::detail {

// Escapes all reserved characters according to RFC 3986 in `x` and
// adds the encoded string to `str`.
CAF_CORE_EXPORT void append_percent_encoded(std::string& str, string_view x,
                                            bool is_path = false);

} // namespace caf::detail
<commit_msg>Add missing include<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include <string>

#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"

namespace caf::detail {

// Escapes all reserved characters according to RFC 3986 in `x` and
// adds the encoded string to `str`.
CAF_CORE_EXPORT void append_percent_encoded(std::string& str, string_view x,
                                            bool is_path = false);

} // namespace caf::detail
<|endoftext|>


<commit_before>/*
 *    _aaaa,  _aa.  sa,  aaa              _aaaa,_  ac  .aa.   .aa.  .aa,  _a, sa
 *  .wWV!!!T  |Wm;  dQ[  $WF            _mWT!"?Y  ]QE  :Q#:   ]QW[  :WWk. ]Q[ dW
 * .jWf       :WW: .dQ[  dQ[           .mW(       )WE  :Q#:  .mSQh. :mWQa.]W[ dQ
 * |QW:       :Wm;  mQ[  dQ[           ]Qk        )Qmi_aQW:  <B:$Qc :WBWQ()W[ dQ
 * |W#:  .ww  ;WW;  dQ[  dQ[  .......  ]Qk        )QB?YYW#:  jf ]Qp.:mE)Qm]Q[ )W
 * +WQ;  :Wm  |Wm; .mQ[  dQ[ :qgggggga ]Qm.       ]WE  :Q# :=QasuQm;:Wk 3QQW[ )Y
 *  ]Wmi.:Wm  +$Q; .mW(  dQ[  !"!!"!!^ dQk,  ._   ]WE  :Q# :3D"!!$Qc.Wk -$WQ[
 *   "?????? ` "?!=m?!   ??'            -??????!  -?!  -?? -?'   "?"-?"  "??' "?
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of darkbits nor the     :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/graphics.hpp"
#include "guichan/exception.hpp"

namespace gcn
{

  Graphics::Graphics()
  {
    mFont = NULL;

  } // end graphics

  bool Graphics::pushClipArea(Rectangle area)
  {
    if (mClipStack.empty())
    {
      ClipRectangle carea;
      carea.x = area.x;
      carea.y = area.y;
      carea.width = area.width;
      carea.height = area.height;
      mClipStack.push(carea);
      return true;
    }

    ClipRectangle top = mClipStack.top();
    ClipRectangle carea;
    carea = area;
    carea.xOffset = top.x + carea.x;
    carea.yOffset = top.y + carea.y;
    carea.x += top.x;
    carea.y += top.y;

    bool result = carea.intersect(top);

    mClipStack.push(carea);

    return result;

  } // end pushClipArea

  void Graphics::popClipArea()
  {

    if (mClipStack.empty())
    {
      throw GCN_EXCEPTION("Graphics::popClipArea. Tried to pop clip area from empty stack.");
    }

    mClipStack.pop();

  } // end popClipArea

  void Graphics::setColor(const Color& color)
  {
    mColor = color;

  } // end setColor

  void Graphics::setFont(Font* font)
  {
    mFont = font;

  } // end setFont

} // end gcn
<commit_msg>Added _beginDraw, _endDraw<commit_after>/*
 *    _aaaa,  _aa.  sa,  aaa              _aaaa,_  ac  .aa.   .aa.  .aa,  _a, sa
 *  .wWV!!!T  |Wm;  dQ[  $WF            _mWT!"?Y  ]QE  :Q#:   ]QW[  :WWk. ]Q[ dW
 * .jWf       :WW: .dQ[  dQ[           .mW(       )WE  :Q#:  .mSQh. :mWQa.]W[ dQ
 * |QW:       :Wm;  mQ[  dQ[           ]Qk        )Qmi_aQW:  <B:$Qc :WBWQ()W[ dQ
 * |W#:  .ww  ;WW;  dQ[  dQ[  .......  ]Qk        )QB?YYW#:  jf ]Qp.:mE)Qm]Q[ )W
 * +WQ;  :Wm  |Wm; .mQ[  dQ[ :qgggggga ]Qm.       ]WE  :Q# :=QasuQm;:Wk 3QQW[ )Y
 *  ]Wmi.:Wm  +$Q; .mW(  dQ[  !"!!"!!^ dQk,  ._   ]WE  :Q# :3D"!!$Qc.Wk -$WQ[
 *   "?????? ` "?!=m?!   ??'            -??????!  -?!  -?? -?'   "?"-?"  "??' "?
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of darkbits nor the     :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "guichan/graphics.hpp"
#include "guichan/exception.hpp"
#include "guichan/font.hpp"

namespace gcn
{

  Graphics::Graphics()
  {
    mFont = NULL;

  } // end graphics

  bool Graphics::pushClipArea(Rectangle area)
  {
    if (mClipStack.empty())
    {
      ClipRectangle carea;
      carea.x = area.x;
      carea.y = area.y;
      carea.width = area.width;
      carea.height = area.height;
      mClipStack.push(carea);
      return true;
    }

    ClipRectangle top = mClipStack.top();
    ClipRectangle carea;
    carea = area;
    carea.xOffset = top.x + carea.x;
    carea.yOffset = top.y + carea.y;
    carea.x += top.x;
    carea.y += top.y;

    bool result = carea.intersect(top);

    mClipStack.push(carea);

    return result;

  } // end pushClipArea

  void Graphics::popClipArea()
  {

    if (mClipStack.empty())
    {
      throw GCN_EXCEPTION("Graphics::popClipArea. Tried to pop clip area from empty stack.");
    }

    mClipStack.pop();

  } // end popClipArea

  void Graphics::drawImage(const Image* image, int dstX, int dstY)
  {
    drawImage(image, 0, 0, dstX, dstY, image->getWidth(), image->getHeight());

  } // end drawImage

  void Graphics::setColor(const Color& color)
  {
    mColor = color;

  } // end setColor

  void Graphics::setFont(Font* font)
  {
    mFont = font;

  } // end setFont

  void Graphics::drawText(const std::string& text, int x, int y)
  {
    if (mFont == NULL)
    {
      throw GCN_EXCEPTION("Graphics::drawText. No font set.");
    }

    for (unsigned int i=0; i< text.size(); ++i)
    {
      mFont->drawGlyph(this, text.at(i), x, y);
      x += mFont->getWidth(text.at(i));
    }

  } // end drawText

} // end gcn
<|endoftext|>