<commit_before>//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

// Peter Grehan (grehan@iprg.nokia.com) coded all of this
// NE2000/ether stuff.

// eth_fbsd.cc - A FreeBSD packet filter implementation of
// an ethernet pktmover. There are some problems and limitations
// with FreeBSD:
//   - the source address of the frame is overwritten by
//    the hosts's source address. This causes problems with
//    learning bridges - since they cannot determine where
//    BOCHS 'is', they broadcast the frame to all ports.
//   - packets cannot be sent from BOCHS to the host
//   - TCP performance seems to be abysmal; I think this is
//     a timing problem somewhere.
//   - I haven't handled the case where multiple frames arrive
//     in a single BPF read.
//
//   The /dev/bpf* devices need to be set up with the appropriate
//  permissions for this to work.
//
//   The config line in .bochsrc should look something like:
//
//  ne2k: ioaddr=0x280, irq=9, mac=00:a:b:c:1:2, ethmod=fbsd, ethdev=fxp0
//

#include "bochs.h"
#ifdef ETH_FBSD
#define LOG_THIS this->

extern "C" {
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/bpf.h>
#include <errno.h>
};

#define BX_BPF_POLL  1000    // Poll for a frame every 1000 usecs

#define BX_BPF_BUFSIZ 2048   // enough for an ether frame + bpf hdr

#define BX_BPF_INSNSIZ  8    // number of bpf insns

// template filter for a unicast mac address and all
// multicast/broadcast frames
static const struct bpf_insn macfilter[] = {
  BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2),
  BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0xaaaaaaaa, 0, 2),
  BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 0),
  BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0000aaaa, 2, 0),
  BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 0),
  BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x01, 0, 1),
  BPF_STMT(BPF_RET, 1514),
  BPF_STMT(BPF_RET, 0),
};

// template filter for all frames
static const struct bpf_insn promiscfilter[] = {
  BPF_STMT(BPF_RET, 1514)
};

//
//  Define the class. This is private to this module
//
class bx_fbsd_pktmover_c : public eth_pktmover_c {
public:
  bx_fbsd_pktmover_c(const char *netif,
		     const char *macaddr,
		     eth_rx_handler_t rxh,
		     void *rxarg);
  void sendpkt(void *buf, unsigned io_len);

private:
  char *fbsd_macaddr[6];
  int bpf_fd;
  static void rx_timer_handler(void *);
  void rx_timer(void);
  int rx_timer_index;
  struct bpf_insn filter[BX_BPF_INSNSIZ];
  FILE *ne2klog, *ne2klog_txt;
};

//
//  Define the static class that registers the derived pktmover class,
// and allocates one on request.
//
class bx_fbsd_locator_c : public eth_locator_c {
public:
  bx_fbsd_locator_c(void) : eth_locator_c("fbsd") {}
protected:
  eth_pktmover_c *allocate(const char *netif,
			   const char *macaddr,
			   eth_rx_handler_t rxh,
			   void *rxarg) {
    return (new bx_fbsd_pktmover_c(netif, macaddr, rxh, rxarg));
  }
} bx_fbsd_match;

//
// Define the methods for the bx_fbsd_pktmover derived class
//

// the constructor
//
// Open a bpf file descriptor, and attempt to bind to
// the specified netif (Replicates libpcap open code)
//
bx_fbsd_pktmover_c::bx_fbsd_pktmover_c(const char *netif,
				       const char *macaddr,
				       eth_rx_handler_t rxh,
				       void *rxarg)
{
  char device[sizeof "/dev/bpf000"];
  int tmpfd;
  int n = 0;
  struct ifreq ifr;
  struct bpf_version bv;
  struct bpf_program bp;
  u_int v;

  memcpy(fbsd_macaddr, macaddr, 6);

  do {
    (void)sprintf(device, "/dev/bpf%d", n++);
    this->bpf_fd = open(device, O_RDWR);
	BX_INFO(("tried %s, returned %d",device,this->bpf_fd));
	if(errno == EACCES)
		break;
  } while (this->bpf_fd == -1);

  if (this->bpf_fd == -1) {
    BX_INFO(("eth_freebsd: could not open packet filter"));
    return;
  }

  if (ioctl(this->bpf_fd, BIOCVERSION, (caddr_t)&bv) < 0) {
    BX_INFO(("eth_freebsd: could not retrieve bpf version"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }
  if (bv.bv_major != BPF_MAJOR_VERSION ||
      bv.bv_minor < BPF_MINOR_VERSION) {
    BX_INFO(("eth_freebsd: bpf version mismatch"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Set buffer size
  v = BX_BPF_BUFSIZ;
  if (ioctl(this->bpf_fd, BIOCSBLEN, (caddr_t)&v) < 0) {
    BX_INFO(("eth_freebsd: could not set buffer size"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  (void)strncpy(ifr.ifr_name, netif, sizeof(ifr.ifr_name));
  if (ioctl(this->bpf_fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
    BX_INFO(("eth_freebsd: could not enable interface %s", netif));
    close(this->bpf_fd);
    this->bpf_fd == -1;
  }

  // Verify that the device is an ethernet.
  if (ioctl(this->bpf_fd, BIOCGDLT, (caddr_t)&v) < 0) {
    BX_INFO(("eth_freebsd: could not retrieve datalink type"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }
  if (v != DLT_EN10MB) {
    BX_INFO(("eth_freebsd: incorrect datalink type %d", v));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Put the device into promisc mode. This could be optimised
  // to filter on a MAC address, broadcast, and all-multi,
  // but this will do for now.
  //
  if (ioctl(this->bpf_fd, BIOCPROMISC, NULL) < 0) {
    BX_INFO(("eth_freebsd: could not enable promisc mode"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Set up non-blocking i/o
  v = 1;
  if (ioctl(this->bpf_fd, FIONBIO, &v) < 0) {
    BX_INFO(("eth_freebsd: could not enable non-blocking i/o"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Install a filter
#ifdef notdef
  memcpy(&this->filter, promiscfilter, sizeof(promiscfilter));
  bp.bf_len   = 1;
#endif
  memcpy(&this->filter, macfilter, sizeof(macfilter));
  this->filter[1].k = (macaddr[2] & 0xff) << 24 |
    (macaddr[3] & 0xff) << 16 |
    (macaddr[4] & 0xff) << 8  |
    (macaddr[5] & 0xff);
  this->filter[3].k = (macaddr[0] & 0xff) << 8 |
    (macaddr[1] & 0xff);
  bp.bf_len   = 8;
  bp.bf_insns = &this->filter[0];
  if (ioctl(this->bpf_fd, BIOCSETF, &bp) < 0) {
    BX_INFO(("eth_freebsd: could not set filter"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Start the rx poll
  this->rx_timer_index =
    bx_pc_system.register_timer(this, this->rx_timer_handler, BX_BPF_POLL,
				1, 1); // continuous, active

  this->rxh   = rxh;
  this->rxarg = rxarg;

#if BX_ETH_FBSD_LOGGING
  // eventually Bryce wants ne2klog to dump in pcap format so that
  // tcpdump -r FILE can read it and interpret packets.
  ne2klog = fopen ("ne2k.raw", "wb");
  if (!ne2klog) BX_PANIC (("open ne2k-tx.log failed"));
  ne2klog_txt = fopen ("ne2k.txt", "wb");
  if (!ne2klog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
  fprintf (ne2klog_txt, "null packetmover readable log file\n");
  fprintf (ne2klog_txt, "net IF = %s\n", netif);
  fprintf (ne2klog_txt, "MAC address = ");
  for (int i=0; i<6; i++)
    fprintf (ne2klog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
  fprintf (ne2klog_txt, "\n--\n");
  fflush (ne2klog_txt);
#endif
}

// the output routine - called with pre-formatted ethernet frame.
void
bx_fbsd_pktmover_c::sendpkt(void *buf, unsigned io_len)
{
#if BX_ETH_FBSD_LOGGING
  BX_DEBUG (("sendpkt length %u", io_len));
  // dump raw bytes to a file, eventually dump in pcap format so that
  // tcpdump -r FILE can interpret them for us.
  int n = fwrite (buf, io_len, 1, ne2klog);
  if (n != 1) BX_ERROR (("fwrite to ne2klog failed", io_len));
  // dump packet in hex into an ascii log file
  fprintf (ne2klog_txt, "NE2K TX packet, length %u\n", io_len);
  Bit8u *charbuf = (Bit8u *)buf;
  for (n=0; n<io_len; n++) {
    if (((n % 16) == 0) && n>0)
      fprintf (ne2klog_txt, "\n");
    fprintf (ne2klog_txt, "%02x ", charbuf[n]);
  }
  fprintf (ne2klog_txt, "\n--\n");
  // flush log so that we see the packets as they arrive w/o buffering
  fflush (ne2klog);
  fflush (ne2klog_txt);
#endif
  int status;

  if (this->bpf_fd != -1)
    status = write(this->bpf_fd, buf, io_len);
}

// The receive poll process
void
bx_fbsd_pktmover_c::rx_timer_handler(void *this_ptr)
{
  bx_fbsd_pktmover_c *class_ptr = (bx_fbsd_pktmover_c *) this_ptr;

  class_ptr->rx_timer();
}

void
bx_fbsd_pktmover_c::rx_timer(void)
{
  int nbytes = 0;
  Bit8u rxbuf[BX_BPF_BUFSIZ];
  struct bpf_hdr *bhdr;

  nbytes = read(this->bpf_fd, rxbuf, sizeof(rxbuf));

  if (nbytes > 0) {
    bhdr = (struct bpf_hdr *) rxbuf;

    // filter out packets sourced from this node
    if (memcmp(rxbuf + bhdr->bh_hdrlen + 6, this->fbsd_macaddr, 6)) {
      (*rxh)(rxarg, rxbuf + bhdr->bh_hdrlen, bhdr->bh_caplen);
    }
#if BX_ETH_FBSD_LOGGING
  /// hey wait there is no receive data with a NULL ethernet, is there....
  if (nbytes > 0) {
    BX_DEBUG (("receive packet length %u", nbytes));
    // dump raw bytes to a file, eventually dump in pcap format so that
    // tcpdump -r FILE can interpret them for us.
    int n = fwrite (rxbuf, nbytes, 1, ne2klog);
    if (n != 1) BX_ERROR (("fwrite to ne2klog failed", nbytes));
    // dump packet in hex into an ascii log file
    fprintf (this->ne2klog_txt, "NE2K RX packet, length %u\n", nbytes);
    Bit8u *charrxbuf = (Bit8u *)rxbuf;
    for (n=0; n<nbytes; n++) {
      if (((n % 16) == 0) && n>0)
	fprintf (this->ne2klog_txt, "\n");
      fprintf (this->ne2klog_txt, "%02x ", rxbuf[n]);
    }
    fprintf (this->ne2klog_txt, "\n--\n");
    // flush log so that we see the packets as they arrive w/o buffering
    fflush (this->ne2klog);
    fflush (this->ne2klog_txt);
  }
#endif

  }
}
#endif

<commit_msg>add strerror to bpf open error<commit_after>//  Copyright (C) 2001  MandrakeSoft S.A.
//
//    MandrakeSoft S.A.
//    43, rue d'Aboukir
//    75002 Paris - France
//    http://www.linux-mandrake.com/
//    http://www.mandrakesoft.com/
//
//  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 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

// Peter Grehan (grehan@iprg.nokia.com) coded all of this
// NE2000/ether stuff.

// eth_fbsd.cc - A FreeBSD packet filter implementation of
// an ethernet pktmover. There are some problems and limitations
// with FreeBSD:
//   - the source address of the frame is overwritten by
//    the hosts's source address. This causes problems with
//    learning bridges - since they cannot determine where
//    BOCHS 'is', they broadcast the frame to all ports.
//   - packets cannot be sent from BOCHS to the host
//   - TCP performance seems to be abysmal; I think this is
//     a timing problem somewhere.
//   - I haven't handled the case where multiple frames arrive
//     in a single BPF read.
//
//   The /dev/bpf* devices need to be set up with the appropriate
//  permissions for this to work.
//
//   The config line in .bochsrc should look something like:
//
//  ne2k: ioaddr=0x280, irq=9, mac=00:a:b:c:1:2, ethmod=fbsd, ethdev=fxp0
//

#include "bochs.h"
#ifdef ETH_FBSD
#define LOG_THIS this->

extern "C" {
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/bpf.h>
#include <errno.h>
};

#define BX_BPF_POLL  1000    // Poll for a frame every 1000 usecs

#define BX_BPF_BUFSIZ 2048   // enough for an ether frame + bpf hdr

#define BX_BPF_INSNSIZ  8    // number of bpf insns

// template filter for a unicast mac address and all
// multicast/broadcast frames
static const struct bpf_insn macfilter[] = {
  BPF_STMT(BPF_LD|BPF_W|BPF_ABS, 2),
  BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0xaaaaaaaa, 0, 2),
  BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 0),
  BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0000aaaa, 2, 0),
  BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 0),
  BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x01, 0, 1),
  BPF_STMT(BPF_RET, 1514),
  BPF_STMT(BPF_RET, 0),
};

// template filter for all frames
static const struct bpf_insn promiscfilter[] = {
  BPF_STMT(BPF_RET, 1514)
};

//
//  Define the class. This is private to this module
//
class bx_fbsd_pktmover_c : public eth_pktmover_c {
public:
  bx_fbsd_pktmover_c(const char *netif,
		     const char *macaddr,
		     eth_rx_handler_t rxh,
		     void *rxarg);
  void sendpkt(void *buf, unsigned io_len);

private:
  char *fbsd_macaddr[6];
  int bpf_fd;
  static void rx_timer_handler(void *);
  void rx_timer(void);
  int rx_timer_index;
  struct bpf_insn filter[BX_BPF_INSNSIZ];
  FILE *ne2klog, *ne2klog_txt;
};

//
//  Define the static class that registers the derived pktmover class,
// and allocates one on request.
//
class bx_fbsd_locator_c : public eth_locator_c {
public:
  bx_fbsd_locator_c(void) : eth_locator_c("fbsd") {}
protected:
  eth_pktmover_c *allocate(const char *netif,
			   const char *macaddr,
			   eth_rx_handler_t rxh,
			   void *rxarg) {
    return (new bx_fbsd_pktmover_c(netif, macaddr, rxh, rxarg));
  }
} bx_fbsd_match;

//
// Define the methods for the bx_fbsd_pktmover derived class
//

// the constructor
//
// Open a bpf file descriptor, and attempt to bind to
// the specified netif (Replicates libpcap open code)
//
bx_fbsd_pktmover_c::bx_fbsd_pktmover_c(const char *netif,
				       const char *macaddr,
				       eth_rx_handler_t rxh,
				       void *rxarg)
{
  char device[sizeof "/dev/bpf000"];
  int tmpfd;
  int n = 0;
  struct ifreq ifr;
  struct bpf_version bv;
  struct bpf_program bp;
  u_int v;

  memcpy(fbsd_macaddr, macaddr, 6);

  do {
    (void)sprintf(device, "/dev/bpf%d", n++);
    this->bpf_fd = open(device, O_RDWR);
	BX_INFO(("tried %s, returned %d (%s)",device,this->bpf_fd,strerror(errno)));
	if(errno == EACCES)
		break;
  } while (this->bpf_fd == -1);

  if (this->bpf_fd == -1) {
    BX_INFO(("eth_freebsd: could not open packet filter"));
    return;
  }

  if (ioctl(this->bpf_fd, BIOCVERSION, (caddr_t)&bv) < 0) {
    BX_INFO(("eth_freebsd: could not retrieve bpf version"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }
  if (bv.bv_major != BPF_MAJOR_VERSION ||
      bv.bv_minor < BPF_MINOR_VERSION) {
    BX_INFO(("eth_freebsd: bpf version mismatch"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Set buffer size
  v = BX_BPF_BUFSIZ;
  if (ioctl(this->bpf_fd, BIOCSBLEN, (caddr_t)&v) < 0) {
    BX_INFO(("eth_freebsd: could not set buffer size"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  (void)strncpy(ifr.ifr_name, netif, sizeof(ifr.ifr_name));
  if (ioctl(this->bpf_fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
    BX_INFO(("eth_freebsd: could not enable interface %s", netif));
    close(this->bpf_fd);
    this->bpf_fd == -1;
  }

  // Verify that the device is an ethernet.
  if (ioctl(this->bpf_fd, BIOCGDLT, (caddr_t)&v) < 0) {
    BX_INFO(("eth_freebsd: could not retrieve datalink type"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }
  if (v != DLT_EN10MB) {
    BX_INFO(("eth_freebsd: incorrect datalink type %d", v));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Put the device into promisc mode. This could be optimised
  // to filter on a MAC address, broadcast, and all-multi,
  // but this will do for now.
  //
  if (ioctl(this->bpf_fd, BIOCPROMISC, NULL) < 0) {
    BX_INFO(("eth_freebsd: could not enable promisc mode"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Set up non-blocking i/o
  v = 1;
  if (ioctl(this->bpf_fd, FIONBIO, &v) < 0) {
    BX_INFO(("eth_freebsd: could not enable non-blocking i/o"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Install a filter
#ifdef notdef
  memcpy(&this->filter, promiscfilter, sizeof(promiscfilter));
  bp.bf_len   = 1;
#endif
  memcpy(&this->filter, macfilter, sizeof(macfilter));
  this->filter[1].k = (macaddr[2] & 0xff) << 24 |
    (macaddr[3] & 0xff) << 16 |
    (macaddr[4] & 0xff) << 8  |
    (macaddr[5] & 0xff);
  this->filter[3].k = (macaddr[0] & 0xff) << 8 |
    (macaddr[1] & 0xff);
  bp.bf_len   = 8;
  bp.bf_insns = &this->filter[0];
  if (ioctl(this->bpf_fd, BIOCSETF, &bp) < 0) {
    BX_INFO(("eth_freebsd: could not set filter"));
    close(this->bpf_fd);
    this->bpf_fd = -1;
    return;
  }

  // Start the rx poll
  this->rx_timer_index =
    bx_pc_system.register_timer(this, this->rx_timer_handler, BX_BPF_POLL,
				1, 1); // continuous, active

  this->rxh   = rxh;
  this->rxarg = rxarg;

#if BX_ETH_FBSD_LOGGING
  // eventually Bryce wants ne2klog to dump in pcap format so that
  // tcpdump -r FILE can read it and interpret packets.
  ne2klog = fopen ("ne2k.raw", "wb");
  if (!ne2klog) BX_PANIC (("open ne2k-tx.log failed"));
  ne2klog_txt = fopen ("ne2k.txt", "wb");
  if (!ne2klog_txt) BX_PANIC (("open ne2k-txdump.txt failed"));
  fprintf (ne2klog_txt, "null packetmover readable log file\n");
  fprintf (ne2klog_txt, "net IF = %s\n", netif);
  fprintf (ne2klog_txt, "MAC address = ");
  for (int i=0; i<6; i++)
    fprintf (ne2klog_txt, "%02x%s", 0xff & macaddr[i], i<5?":" : "");
  fprintf (ne2klog_txt, "\n--\n");
  fflush (ne2klog_txt);
#endif
}

// the output routine - called with pre-formatted ethernet frame.
void
bx_fbsd_pktmover_c::sendpkt(void *buf, unsigned io_len)
{
#if BX_ETH_FBSD_LOGGING
  BX_DEBUG (("sendpkt length %u", io_len));
  // dump raw bytes to a file, eventually dump in pcap format so that
  // tcpdump -r FILE can interpret them for us.
  int n = fwrite (buf, io_len, 1, ne2klog);
  if (n != 1) BX_ERROR (("fwrite to ne2klog failed", io_len));
  // dump packet in hex into an ascii log file
  fprintf (ne2klog_txt, "NE2K TX packet, length %u\n", io_len);
  Bit8u *charbuf = (Bit8u *)buf;
  for (n=0; n<io_len; n++) {
    if (((n % 16) == 0) && n>0)
      fprintf (ne2klog_txt, "\n");
    fprintf (ne2klog_txt, "%02x ", charbuf[n]);
  }
  fprintf (ne2klog_txt, "\n--\n");
  // flush log so that we see the packets as they arrive w/o buffering
  fflush (ne2klog);
  fflush (ne2klog_txt);
#endif
  int status;

  if (this->bpf_fd != -1)
    status = write(this->bpf_fd, buf, io_len);
}

// The receive poll process
void
bx_fbsd_pktmover_c::rx_timer_handler(void *this_ptr)
{
  bx_fbsd_pktmover_c *class_ptr = (bx_fbsd_pktmover_c *) this_ptr;

  class_ptr->rx_timer();
}

void
bx_fbsd_pktmover_c::rx_timer(void)
{
  int nbytes = 0;
  Bit8u rxbuf[BX_BPF_BUFSIZ];
  struct bpf_hdr *bhdr;

  nbytes = read(this->bpf_fd, rxbuf, sizeof(rxbuf));

  if (nbytes > 0) {
    bhdr = (struct bpf_hdr *) rxbuf;

    // filter out packets sourced from this node
    if (memcmp(rxbuf + bhdr->bh_hdrlen + 6, this->fbsd_macaddr, 6)) {
      (*rxh)(rxarg, rxbuf + bhdr->bh_hdrlen, bhdr->bh_caplen);
    }
#if BX_ETH_FBSD_LOGGING
  /// hey wait there is no receive data with a NULL ethernet, is there....
  if (nbytes > 0) {
    BX_DEBUG (("receive packet length %u", nbytes));
    // dump raw bytes to a file, eventually dump in pcap format so that
    // tcpdump -r FILE can interpret them for us.
    int n = fwrite (rxbuf, nbytes, 1, ne2klog);
    if (n != 1) BX_ERROR (("fwrite to ne2klog failed", nbytes));
    // dump packet in hex into an ascii log file
    fprintf (this->ne2klog_txt, "NE2K RX packet, length %u\n", nbytes);
    Bit8u *charrxbuf = (Bit8u *)rxbuf;
    for (n=0; n<nbytes; n++) {
      if (((n % 16) == 0) && n>0)
	fprintf (this->ne2klog_txt, "\n");
      fprintf (this->ne2klog_txt, "%02x ", rxbuf[n]);
    }
    fprintf (this->ne2klog_txt, "\n--\n");
    // flush log so that we see the packets as they arrive w/o buffering
    fflush (this->ne2klog);
    fflush (this->ne2klog_txt);
  }
#endif

  }
}
#endif

<|endoftext|>


<commit_before>#include "common/lazyworld.h"
#include <cstdio>

void LazyWorld::DoStep() {
    // Collision check against player
}

void LazyWorld::CheckCollision(Entity *entity) {
    PositionedBlock *block;

    for (std::list<PositionedBlock*>::iterator it = VisibleBlocks.begin(); it != VisibleBlocks.end(); ++it) {
        block = *it;
        if (block->block->Type == 0) continue;

        if (entity->Pos.X + entity->Hitbox.X >= block->pos.X && entity->Pos.X <= block->pos.X + 1
         && entity->Pos.Y + entity->Hitbox.Y >= block->pos.Y && entity->Pos.Y <= block->pos.Y + 1
         && entity->Pos.Z + entity->Hitbox.Z >= block->pos.Z && entity->Pos.Z <= block->pos.Z + 1)
            entity->Collide(*block);
    }
}

PositionedBlock *LazyWorld::CheckAim(Player *player) {
    PositionedBlock *block;
    Ray ray = Ray(player);

    PositionedBlock *target = NULL;
    float dist, best = 5.f;

    for (std::list<PositionedBlock*>::iterator it = VisibleBlocks.begin(); it != VisibleBlocks.end(); ++it) {
        block = *it; // Blocks[i];

        dist = ray.CheckCollision(block);
        if (0.f < dist && dist < best) {
            best = dist;
            target = block;
        }
    }

    if (target != NULL)
        target->marked = true;

    return target;
}

void LazyWorld::DestroyTarget(Player *player) {
    PositionedBlock *block = CheckAim(player);
    if (!block) return;

    DestroyBlock(block);
}

void LazyWorld::DestroyBlock(PositionedBlock *block) {
    Vector3 chunk, pos;

    chunk.X = floor(block->pos.X / ChunkSize);
    chunk.Y = floor(block->pos.Y / ChunkSize);
    chunk.Z = floor(block->pos.Z / ChunkSize);

    // TODO: handle variable chunk sizes
    PlaceBlock(0, chunk, block->pos - (chunk * 16));

    // TODO
    //context->socket->SendBlock(0, chunkIndex, blockIndex);
    sf::Packet Packet;
    Packet << (sf::Uint8) 9 << (sf::Uint8) 0 << chunk << pos;
    Socket.Send(Packet);
}

Block *MakeBlock(char type) {
    if (type == 3)
        return new GrassBlock();
    else
        return new AirBlock();
}

void LazyWorld::PlaceBlock(char type, Vector3 chunkIndex, Vector3 blockIndex) {
    // TODO: check if the block is visible before doing this loop
    // TODO: handle variable chunk sizes
    Vector3 absolute = (chunkIndex * 16) + blockIndex;
    for (std::list<PositionedBlock*>::iterator it = VisibleBlocks.begin(); it != VisibleBlocks.end(); ++it) {
        if ((*it)->pos == absolute) {
            VisibleBlocks.remove(*it);
            break;
        }
    }

    std::map<Vector3, Block*> chunk = LoadedChunks[chunkIndex];
    if (chunk.size() == 0) return; // chunk isn't loaded, don't bother

    Block *blk = MakeBlock(type);
    chunk[blockIndex] = blk;
    if (type != 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex, 1));

    // TODO: handle placing blocks without just counting on a [reliable] glitch!

    if (blockIndex.X > 0 && chunk[blockIndex - Vector3(1, 0, 0)]->Type > 0) {
        blk = chunk[blockIndex - Vector3(1, 0, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex - Vector3(1, 0, 0), 1));
        blk->faces |= 0x08;
    }

    if (blockIndex.Y > 0 && chunk[blockIndex - Vector3(0, 1, 0)]->Type > 0) {
        blk = chunk[blockIndex - Vector3(0, 1, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex - Vector3(0, 1, 0), 1));
        blk->faces |= 0x10;
    }

    if (blockIndex.Z > 0 && chunk[blockIndex - Vector3(0, 0, 1)]->Type > 0) {
        blk = chunk[blockIndex - Vector3(0, 0, 1)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex - Vector3(0, 0, 1), 1));
        blk->faces |= 0x20;
    }

    // TODO: handle variable chunk sizes
    if (blockIndex.X < 15 && chunk[blockIndex + Vector3(1, 0, 0)]->Type > 0) {
        blk = chunk[blockIndex + Vector3(1, 0, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex + Vector3(1, 0, 0), 1));
        blk->faces |= 0x01;
    }

    if (blockIndex.Y < 15 && chunk[blockIndex + Vector3(0, 1, 0)]->Type > 0) {
        blk = chunk[blockIndex + Vector3(0, 1, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex + Vector3(0, 1, 0), 1));
        blk->faces |= 0x02;
    }

    if (blockIndex.Z < 15 && chunk[blockIndex + Vector3(0, 0, 1)]->Type > 0) {
        blk = chunk[blockIndex + Vector3(0, 0, 1)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, blockIndex + Vector3(0, 0, 1), 1));
        blk->faces |= 0x04;
    }
}

bool contains(std::vector<Vector3> vector, Vector3 value) {
    for (int i = 0; i < vector.size(); i++)
        if (vector[i] == value) return true;

    return false;
}

void LazyWorld::LoadChunk(sf::Packet Packet) {
    int BlockCount;
    Vector3 ChunkIndex; // TODO: remove from request list, add to loaded list
    Packet >> ChunkIndex >> BlockCount;

    std::map<Vector3, Block*> chunk;

    sf::Uint8 type;
    Block *block;
    Vector3 Pos;
    float SideLength;

    for (int i = 0; i < BlockCount; i++) {
        Packet >> type >> Pos;

        chunk[Vector3(Pos)] = MakeBlock(type);
    }

    for (std::map<Vector3, Block*>::iterator it = chunk.begin(); it != chunk.end(); ++it) {
        if (it->second->Type == 0) continue;
        Pos = it->first;

        char sides = 0x3F;

        if (Pos.X > 0 && chunk[Pos - Vector3(1, 0, 0)]->Type > 0)
            sides &= (0xFE); // 0b00000001

        if (Pos.Y > 0 && chunk[Pos - Vector3(0, 1, 0)]->Type > 0)
            sides &= (0xFD); // 0b00000010

        if (Pos.Z > 0 && chunk[Pos - Vector3(0, 0, 1)]->Type > 0)
            sides &= (0xFB); // 0b00000100

        // TODO: handle variable chunk sizes

        if (Pos.X < 15 && chunk[Pos + Vector3(1, 0, 0)]->Type > 0)
            sides &= (0xF7); // 0b00001000

        if (Pos.Y < 15 && chunk[Pos + Vector3(0, 1, 0)]->Type > 0)
            sides &= (0xEF); // 0b00010000

        if (Pos.Z < 15 && chunk[Pos + Vector3(0, 0, 1)]->Type > 0)
            sides &= (0xDF); // 0b00100000

        it->second->faces = sides;

        if (sides > 0)
            VisibleBlocks.push_back(new PositionedBlock(it->second, (ChunkIndex * 16) + Pos, 1));
    }

    LoadedChunks[ChunkIndex] = chunk;
}

void LazyWorld::HandleRequests(Vector3 Pos) {
    Vector3 CurrentChunk;

    CurrentChunk.X = floor(Pos.X / ChunkSize);
    CurrentChunk.Y = floor(Pos.Y / ChunkSize);
    CurrentChunk.Z = floor(Pos.Z / ChunkSize);

    // TODO: lol.
    RequestChunk(CurrentChunk);
    RequestChunk(CurrentChunk + Vector3(-1, 0,  0));
    RequestChunk(CurrentChunk + Vector3(-1, -1, 0));
    RequestChunk(CurrentChunk + Vector3(0,  -1, 0));
    RequestChunk(CurrentChunk + Vector3(1,  -1, 0));
    RequestChunk(CurrentChunk + Vector3(1,  0,  0));
    RequestChunk(CurrentChunk + Vector3(1,  1,  0));
    RequestChunk(CurrentChunk + Vector3(0,  1,  0));
    RequestChunk(CurrentChunk + Vector3(-1, 1,  0));
}

void LazyWorld::RequestChunk(Vector3 ChunkIndex) {
    if (contains(RequestedChunks, ChunkIndex)) return;

    // Send request to the server
    sf::Packet Packet;
    Packet << (sf::Uint8) 4 << ChunkIndex;
    Socket.Send(Packet);

    RequestedChunks.push_back(ChunkIndex);
}
<commit_msg>Fix for block placing<commit_after>#include "common/lazyworld.h"
#include <cstdio>

void LazyWorld::DoStep() {
    // Collision check against player
}

void LazyWorld::CheckCollision(Entity *entity) {
    PositionedBlock *block;

    for (std::list<PositionedBlock*>::iterator it = VisibleBlocks.begin(); it != VisibleBlocks.end(); ++it) {
        block = *it;
        if (block->block->Type == 0) continue;

        if (entity->Pos.X + entity->Hitbox.X >= block->pos.X && entity->Pos.X <= block->pos.X + 1
         && entity->Pos.Y + entity->Hitbox.Y >= block->pos.Y && entity->Pos.Y <= block->pos.Y + 1
         && entity->Pos.Z + entity->Hitbox.Z >= block->pos.Z && entity->Pos.Z <= block->pos.Z + 1)
            entity->Collide(*block);
    }
}

PositionedBlock *LazyWorld::CheckAim(Player *player) {
    PositionedBlock *block;
    Ray ray = Ray(player);

    PositionedBlock *target = NULL;
    float dist, best = 5.f;

    for (std::list<PositionedBlock*>::iterator it = VisibleBlocks.begin(); it != VisibleBlocks.end(); ++it) {
        block = *it; // Blocks[i];

        dist = ray.CheckCollision(block);
        if (0.f < dist && dist < best) {
            best = dist;
            target = block;
        }
    }

    if (target != NULL)
        target->marked = true;

    return target;
}

void LazyWorld::DestroyTarget(Player *player) {
    PositionedBlock *block = CheckAim(player);
    if (!block) return;

    DestroyBlock(block);
}

void LazyWorld::DestroyBlock(PositionedBlock *block) {
    Vector3 chunk, pos;

    chunk.X = floor(block->pos.X / ChunkSize);
    chunk.Y = floor(block->pos.Y / ChunkSize);
    chunk.Z = floor(block->pos.Z / ChunkSize);
    pos = block->pos - (chunk * 16); // TODO: handle variable chunk sizes

    PlaceBlock(0, chunk, pos);

    // TODO
    //context->socket->SendBlock(0, chunk, pos);
    sf::Packet Packet;
    Packet << (sf::Uint8) 9 << (sf::Uint8) 0 << chunk << pos;
    Socket.Send(Packet);
}

Block *MakeBlock(char type) {
    if (type == 3)
        return new GrassBlock();
    else
        return new AirBlock();
}

void LazyWorld::PlaceBlock(char type, Vector3 chunkIndex, Vector3 blockIndex) {
    // TODO: check if the block is visible before doing this loop
    // TODO: handle variable chunk sizes
    Vector3 absolute = (chunkIndex * 16) + blockIndex;
    for (std::list<PositionedBlock*>::iterator it = VisibleBlocks.begin(); it != VisibleBlocks.end(); ++it) {
        if ((*it)->pos == absolute) {
            VisibleBlocks.remove(*it);
            break;
        }
    }

    std::map<Vector3, Block*> chunk = LoadedChunks[chunkIndex];
    if (chunk.size() == 0) return; // chunk isn't loaded, don't bother

    Block *blk = MakeBlock(type);
    chunk[blockIndex] = blk;
    if (type != 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute, 1));

    // TODO: handle placing blocks without just counting on a [reliable] glitch!

    if (blockIndex.X > 0 && chunk[blockIndex - Vector3(1, 0, 0)]->Type > 0) {
        blk = chunk[blockIndex - Vector3(1, 0, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute - Vector3(1, 0, 0), 1));
        blk->faces |= 0x08;
    }

    if (blockIndex.Y > 0 && chunk[blockIndex - Vector3(0, 1, 0)]->Type > 0) {
        blk = chunk[blockIndex - Vector3(0, 1, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute - Vector3(0, 1, 0), 1));
        blk->faces |= 0x10;
    }

    if (blockIndex.Z > 0 && chunk[blockIndex - Vector3(0, 0, 1)]->Type > 0) {
        blk = chunk[blockIndex - Vector3(0, 0, 1)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute - Vector3(0, 0, 1), 1));
        blk->faces |= 0x20;
    }

    // TODO: handle variable chunk sizes
    if (blockIndex.X < 15 && chunk[blockIndex + Vector3(1, 0, 0)]->Type > 0) {
        blk = chunk[blockIndex + Vector3(1, 0, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute + Vector3(1, 0, 0), 1));
        blk->faces |= 0x01;
    }

    if (blockIndex.Y < 15 && chunk[blockIndex + Vector3(0, 1, 0)]->Type > 0) {
        blk = chunk[blockIndex + Vector3(0, 1, 0)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute + Vector3(0, 1, 0), 1));
        blk->faces |= 0x02;
    }

    if (blockIndex.Z < 15 && chunk[blockIndex + Vector3(0, 0, 1)]->Type > 0) {
        blk = chunk[blockIndex + Vector3(0, 0, 1)];
        if (blk->faces == 0) VisibleBlocks.push_back(new PositionedBlock(blk, absolute + Vector3(0, 0, 1), 1));
        blk->faces |= 0x04;
    }
}

bool contains(std::vector<Vector3> vector, Vector3 value) {
    for (int i = 0; i < vector.size(); i++)
        if (vector[i] == value) return true;

    return false;
}

void LazyWorld::LoadChunk(sf::Packet Packet) {
    int BlockCount;
    Vector3 ChunkIndex; // TODO: remove from request list, add to loaded list
    Packet >> ChunkIndex >> BlockCount;

    std::map<Vector3, Block*> chunk;

    sf::Uint8 type;
    Block *block;
    Vector3 Pos;
    float SideLength;

    for (int i = 0; i < BlockCount; i++) {
        Packet >> type >> Pos;

        chunk[Vector3(Pos)] = MakeBlock(type);
    }

    for (std::map<Vector3, Block*>::iterator it = chunk.begin(); it != chunk.end(); ++it) {
        if (it->second->Type == 0) continue;
        Pos = it->first;

        char sides = 0x3F;

        if (Pos.X > 0 && chunk[Pos - Vector3(1, 0, 0)]->Type > 0)
            sides &= (0xFE); // 0b00000001

        if (Pos.Y > 0 && chunk[Pos - Vector3(0, 1, 0)]->Type > 0)
            sides &= (0xFD); // 0b00000010

        if (Pos.Z > 0 && chunk[Pos - Vector3(0, 0, 1)]->Type > 0)
            sides &= (0xFB); // 0b00000100

        // TODO: handle variable chunk sizes

        if (Pos.X < 15 && chunk[Pos + Vector3(1, 0, 0)]->Type > 0)
            sides &= (0xF7); // 0b00001000

        if (Pos.Y < 15 && chunk[Pos + Vector3(0, 1, 0)]->Type > 0)
            sides &= (0xEF); // 0b00010000

        if (Pos.Z < 15 && chunk[Pos + Vector3(0, 0, 1)]->Type > 0)
            sides &= (0xDF); // 0b00100000

        it->second->faces = sides;

        if (sides > 0)
            VisibleBlocks.push_back(new PositionedBlock(it->second, (ChunkIndex * 16) + Pos, 1));
    }

    LoadedChunks[ChunkIndex] = chunk;
}

void LazyWorld::HandleRequests(Vector3 Pos) {
    Vector3 CurrentChunk;

    CurrentChunk.X = floor(Pos.X / ChunkSize);
    CurrentChunk.Y = floor(Pos.Y / ChunkSize);
    CurrentChunk.Z = floor(Pos.Z / ChunkSize);

    // TODO: lol.
    RequestChunk(CurrentChunk);
    RequestChunk(CurrentChunk + Vector3(-1, 0,  0));
    RequestChunk(CurrentChunk + Vector3(-1, -1, 0));
    RequestChunk(CurrentChunk + Vector3(0,  -1, 0));
    RequestChunk(CurrentChunk + Vector3(1,  -1, 0));
    RequestChunk(CurrentChunk + Vector3(1,  0,  0));
    RequestChunk(CurrentChunk + Vector3(1,  1,  0));
    RequestChunk(CurrentChunk + Vector3(0,  1,  0));
    RequestChunk(CurrentChunk + Vector3(-1, 1,  0));
}

void LazyWorld::RequestChunk(Vector3 ChunkIndex) {
    if (contains(RequestedChunks, ChunkIndex)) return;

    // Send request to the server
    sf::Packet Packet;
    Packet << (sf::Uint8) 4 << ChunkIndex;
    Socket.Send(Packet);

    RequestedChunks.push_back(ChunkIndex);
}
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"
#include "condor_network.h"
#include "condor_config.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "condor_attributes.h"

#include "MyString.h"

#include "condor_commands.h"
#include "condor_io.h"

//------------------------------------------------------------------------

static int CalcTime(int,int,int);
static int TimeLine(const MyString& Name,int FromDate, int ToDate, int Res);

//------------------------------------------------------------------------

static void Usage(char* name)
{
  fprintf(stderr, "Usage: %s [-f filename] [-orgformat] [-pool hostname] [-lastday | -lastweek | -lastmonth | -lasthours h | -from m d y [-to m d y]] {-resourcequery <name> | -resourcelist | -resgroupquery <name> | -resgrouplist | -userquery <name> | -userlist | -usergroupquery <name> | -usergrouplist | -ckptquery | -ckptlist}\n",name);
  exit(1);
}

//------------------------------------------------------------------------

const int MinuteSec=60;
const int HourSec=MinuteSec*60;
const int DaySec=HourSec*24;
const int WeekSec=DaySec*7;
const int MonthSec=DaySec*30;
const int YearSec=DaySec*365;

//------------------------------------------------------------------------

/*
int GrpConvStr(char* InpStr, char* OutStr)
{
  float T,Unclaimed, Matched, Claimed,Preempting,Owner;
  if (sscanf(InpStr," %f %f %f %f %f %f",&T,&Unclaimed,&Matched,&Claimed,&Preempting,&Owner)!=6) return -1;
  sprintf(OutStr,"%f\t%f\t%f\t%f\t%f\t%f\n",T,Unclaimed,Matched,Claimed,Preempting,Owner);
  return 0;
}
*/

//------------------------------------------------------------------------

int ResConvStr(char* InpStr, char* OutStr)
{
  float T,LoadAvg;
  int KbdIdle;
  int State;
  if (sscanf(InpStr," %f %d %f %d",&T,&KbdIdle,&LoadAvg,&State)!=4) return -1;
  char* StateName[]={"UNCLAIMED","MATCHED","CLAIMED","PRE-EMPTING","OWNER"};
  sprintf(OutStr,"%f\t%d\t%f\t%s\n",T,KbdIdle,LoadAvg,StateName[State-1]);
  return 0;
}

//------------------------------------------------------------------------

main(int argc, char* argv[])
{
  int Now=time(0);
  int ToDate=Now;
  int FromDate=ToDate-DaySec;
  int Options=0;

  int QueryType=-1;
  MyString QueryArg;

  MyString FileName;
  MyString TimeFileName;
  MyString CondorViewHost;

  for(int i=1; i<argc; i++) {

    // Analyze date specifiers

    if (strcmp(argv[i],"-lastday")==0) {
      ToDate=Now;
      FromDate=ToDate-DaySec;
    }
    else if (strcmp(argv[i],"-lastweek")==0) {
      ToDate=Now;
      FromDate=ToDate-WeekSec;
    }
    else if (strcmp(argv[i],"-lastmonth")==0) {
      ToDate=Now;
      FromDate=ToDate-MonthSec;
    }
    else if (strcmp(argv[i],"-lasthours")==0) {
      if (argc-i<=1) Usage(argv[0]);
      int hours=atoi(argv[i+1]);
      ToDate=Now;
      FromDate=ToDate-HourSec*hours;
      i++;
    }
    else if (strcmp(argv[i],"-from")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      FromDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,FromDate);
      i+=3;
    }
    else if (strcmp(argv[i],"-to")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      ToDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,ToDate);
      i+=3;
    }

    // Query type

    else if (strcmp(argv[i],"-resourcelist")==0) {
      QueryType=QUERY_HIST_STARTD_LIST;
    }
    else if (strcmp(argv[i],"-resourcequery")==0) {
      QueryType=QUERY_HIST_STARTD;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-resgrouplist")==0) {
      QueryType=QUERY_HIST_GROUPS_LIST;
    }
    else if (strcmp(argv[i],"-resgroupquery")==0) {
      QueryType=QUERY_HIST_GROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-userlist")==0) {
      QueryType=QUERY_HIST_SUBMITTOR_LIST;
    }
    else if (strcmp(argv[i],"-userquery")==0) {
      QueryType=QUERY_HIST_SUBMITTOR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-usergrouplist")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS_LIST;
    }
    else if (strcmp(argv[i],"-usergroupquery")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-ckptlist")==0) {
      QueryType=QUERY_HIST_CKPTSRVR_LIST;
    }
    else if (strcmp(argv[i],"-ckptquery")==0) {
      QueryType=QUERY_HIST_CKPTSRVR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }

    // miscaleneous

    else if (strcmp(argv[i],"-f")==0) {
      if (argc-i<=1) Usage(argv[0]);
      FileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-timedat")==0) {
      if (argc-i<=1) Usage(argv[0]);
      TimeFileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-orgformat")==0) {
      Options=1;
	}
    else if (strcmp(argv[i],"-pool")==0) {
      if (argc-i<=1) Usage(argv[0]);
      CondorViewHost=argv[i+1];
      i++;
    }
    else {
      Usage(argv[0]);
    }
  }

  // Check validity or arguments
  if (QueryType==-1 || FromDate<0 || FromDate>Now || ToDate<FromDate) Usage(argv[0]);
  // if (ToDate>Now) ToDate=Now;

  if (CondorViewHost.Length()==0) {
    config( 0 );
    char* tmp=param("CONDOR_VIEW_HOST");
    if (!tmp) {
      tmp=param("COLLECTOR_HOST");
      if (!tmp) {
        fprintf(stderr, "No CONDOR_VIEW_HOST or COLLECTOR_HOST  specified in config file\n");
        exit(1);
      }
    }
    CondorViewHost=tmp;
  }

  int MaxLen=200;
  char Line[MaxLen+1];
  char* LinePtr=Line;

  if (QueryArg.Length()>MaxLen) {
    fprintf(stderr, "Command line argument is too long\n");
    exit(1);
  }
  strcpy(LinePtr, QueryArg.Value());

  if (TimeFileName.Length()>0) TimeLine(TimeFileName,FromDate,ToDate,10);

  // Open the output file
  FILE* outfile=stdout;
  if (FileName.Length()>0) outfile=fopen(FileName.Value(),"w");

  int LineCount=0;

  ReliSock sock;
  if (!sock.connect((char*) CondorViewHost.Value(), COLLECTOR_PORT)) {
    fprintf(stderr, "failed to connect to the CondorView server\n");
    fputs("No Data.\n",outfile);
    exit(1);
  }

  sock.encode();
  if (!sock.code(QueryType) ||
      !sock.code(FromDate) ||
      !sock.code(ToDate) ||
      !sock.code(Options) ||
      !sock.code(LinePtr) ||
      !sock.end_of_message()) {
    fprintf(stderr, "failed to send query to the CondorView server\n");
    fputs("No Data.\n",outfile);
    exit(1);
  }

  char NewStr[200];

  sock.decode();
  while(1) {
    if (!sock.code(LinePtr)) {
      fprintf(stderr, "failed to receive data from the CondorView server\n");
      if (LineCount==0) fputs("No Data.\n",outfile);
      exit(1);
    }
    if (strlen(LinePtr)==0) break;
    LineCount++;
    if (Options==0 && QueryType==QUERY_HIST_STARTD) {
      ResConvStr(LinePtr,NewStr);
      fputs(NewStr,outfile);
    }
    else {
      fputs(LinePtr,outfile);
    }
  }
  if (!sock.end_of_message()) {
    fprintf(stderr, "failed to receive data from the CondorView server\n");
  }

  if (LineCount==0) fputs("No Data.\n",outfile);
  if (FileName.Length()>0) fclose(outfile);

  return 0;
}

int CalcTime(int month, int day, int year) {
  struct tm time_str;
  if (year>1900) year-=1900;
  time_str.tm_year=year;
  time_str.tm_mon=month-1;
  time_str.tm_mday=day;
  time_str.tm_hour=0;
  time_str.tm_min=0;
  time_str.tm_sec=0;
  time_str.tm_isdst=-1;
  return mktime(&time_str);
}

int TimeLine(const MyString& TimeFileName,int FromDate, int ToDate, int Res)
{
  double Interval=double(ToDate-FromDate)/double(Res);
  float RelT;
  time_t T;
  FILE* TimeFile=fopen(TimeFileName.Value(),"w");
  if (!TimeFile) return -1;
  for (int i=0; i<=Res; i++) {
    T=(time_t)FromDate+((int)Interval*i);
    RelT=float(100.0/Res)*i;
	fprintf(TimeFile,"%.2f\t%s",RelT,asctime(localtime(&T)));
  }
  fclose(TimeFile);
  return 0;
}
<commit_msg>fixed C++ error: MaxLen needs to be a const before Visual C++ will compile<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"
#include "condor_network.h"
#include "condor_config.h"
#include "condor_classad.h"
#include "condor_debug.h"
#include "condor_attributes.h"

#include "MyString.h"

#include "condor_commands.h"
#include "condor_io.h"

//------------------------------------------------------------------------

static int CalcTime(int,int,int);
static int TimeLine(const MyString& Name,int FromDate, int ToDate, int Res);

//------------------------------------------------------------------------

static void Usage(char* name)
{
  fprintf(stderr, "Usage: %s [-f filename] [-orgformat] [-pool hostname] [-lastday | -lastweek | -lastmonth | -lasthours h | -from m d y [-to m d y]] {-resourcequery <name> | -resourcelist | -resgroupquery <name> | -resgrouplist | -userquery <name> | -userlist | -usergroupquery <name> | -usergrouplist | -ckptquery | -ckptlist}\n",name);
  exit(1);
}

//------------------------------------------------------------------------

const int MinuteSec=60;
const int HourSec=MinuteSec*60;
const int DaySec=HourSec*24;
const int WeekSec=DaySec*7;
const int MonthSec=DaySec*30;
const int YearSec=DaySec*365;

//------------------------------------------------------------------------

/*
int GrpConvStr(char* InpStr, char* OutStr)
{
  float T,Unclaimed, Matched, Claimed,Preempting,Owner;
  if (sscanf(InpStr," %f %f %f %f %f %f",&T,&Unclaimed,&Matched,&Claimed,&Preempting,&Owner)!=6) return -1;
  sprintf(OutStr,"%f\t%f\t%f\t%f\t%f\t%f\n",T,Unclaimed,Matched,Claimed,Preempting,Owner);
  return 0;
}
*/

//------------------------------------------------------------------------

int ResConvStr(char* InpStr, char* OutStr)
{
  float T,LoadAvg;
  int KbdIdle;
  int State;
  if (sscanf(InpStr," %f %d %f %d",&T,&KbdIdle,&LoadAvg,&State)!=4) return -1;
  char* StateName[]={"UNCLAIMED","MATCHED","CLAIMED","PRE-EMPTING","OWNER"};
  sprintf(OutStr,"%f\t%d\t%f\t%s\n",T,KbdIdle,LoadAvg,StateName[State-1]);
  return 0;
}

//------------------------------------------------------------------------

main(int argc, char* argv[])
{
  int Now=time(0);
  int ToDate=Now;
  int FromDate=ToDate-DaySec;
  int Options=0;

  int QueryType=-1;
  MyString QueryArg;

  MyString FileName;
  MyString TimeFileName;
  MyString CondorViewHost;

  for(int i=1; i<argc; i++) {

    // Analyze date specifiers

    if (strcmp(argv[i],"-lastday")==0) {
      ToDate=Now;
      FromDate=ToDate-DaySec;
    }
    else if (strcmp(argv[i],"-lastweek")==0) {
      ToDate=Now;
      FromDate=ToDate-WeekSec;
    }
    else if (strcmp(argv[i],"-lastmonth")==0) {
      ToDate=Now;
      FromDate=ToDate-MonthSec;
    }
    else if (strcmp(argv[i],"-lasthours")==0) {
      if (argc-i<=1) Usage(argv[0]);
      int hours=atoi(argv[i+1]);
      ToDate=Now;
      FromDate=ToDate-HourSec*hours;
      i++;
    }
    else if (strcmp(argv[i],"-from")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      FromDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,FromDate);
      i+=3;
    }
    else if (strcmp(argv[i],"-to")==0) {
      if (argc-i<=3) Usage(argv[0]);
      int month=atoi(argv[i+1]);
      int day=atoi(argv[i+2]);
      int year=atoi(argv[i+3]);
      ToDate=CalcTime(month,day,year);
      // printf("Date translation: %d/%d/%d = %d\n",month,day,year,ToDate);
      i+=3;
    }

    // Query type

    else if (strcmp(argv[i],"-resourcelist")==0) {
      QueryType=QUERY_HIST_STARTD_LIST;
    }
    else if (strcmp(argv[i],"-resourcequery")==0) {
      QueryType=QUERY_HIST_STARTD;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-resgrouplist")==0) {
      QueryType=QUERY_HIST_GROUPS_LIST;
    }
    else if (strcmp(argv[i],"-resgroupquery")==0) {
      QueryType=QUERY_HIST_GROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-userlist")==0) {
      QueryType=QUERY_HIST_SUBMITTOR_LIST;
    }
    else if (strcmp(argv[i],"-userquery")==0) {
      QueryType=QUERY_HIST_SUBMITTOR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-usergrouplist")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS_LIST;
    }
    else if (strcmp(argv[i],"-usergroupquery")==0) {
      QueryType=QUERY_HIST_SUBMITTORGROUPS;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-ckptlist")==0) {
      QueryType=QUERY_HIST_CKPTSRVR_LIST;
    }
    else if (strcmp(argv[i],"-ckptquery")==0) {
      QueryType=QUERY_HIST_CKPTSRVR;
      if (argc-i<=1) Usage(argv[0]);
      QueryArg=argv[i+1];
      i++;
    }

    // miscaleneous

    else if (strcmp(argv[i],"-f")==0) {
      if (argc-i<=1) Usage(argv[0]);
      FileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-timedat")==0) {
      if (argc-i<=1) Usage(argv[0]);
      TimeFileName=argv[i+1];
      i++;
    }
    else if (strcmp(argv[i],"-orgformat")==0) {
      Options=1;
	}
    else if (strcmp(argv[i],"-pool")==0) {
      if (argc-i<=1) Usage(argv[0]);
      CondorViewHost=argv[i+1];
      i++;
    }
    else {
      Usage(argv[0]);
    }
  }

  // Check validity or arguments
  if (QueryType==-1 || FromDate<0 || FromDate>Now || ToDate<FromDate) Usage(argv[0]);
  // if (ToDate>Now) ToDate=Now;

  if (CondorViewHost.Length()==0) {
    config( 0 );
    char* tmp=param("CONDOR_VIEW_HOST");
    if (!tmp) {
      tmp=param("COLLECTOR_HOST");
      if (!tmp) {
        fprintf(stderr, "No CONDOR_VIEW_HOST or COLLECTOR_HOST  specified in config file\n");
        exit(1);
      }
    }
    CondorViewHost=tmp;
  }

  const int MaxLen=200;
  char Line[MaxLen+1];
  char* LinePtr=Line;

  if (QueryArg.Length()>MaxLen) {
    fprintf(stderr, "Command line argument is too long\n");
    exit(1);
  }
  strcpy(LinePtr, QueryArg.Value());

  if (TimeFileName.Length()>0) TimeLine(TimeFileName,FromDate,ToDate,10);

  // Open the output file
  FILE* outfile=stdout;
  if (FileName.Length()>0) outfile=fopen(FileName.Value(),"w");

  int LineCount=0;

  ReliSock sock;
  if (!sock.connect((char*) CondorViewHost.Value(), COLLECTOR_PORT)) {
    fprintf(stderr, "failed to connect to the CondorView server\n");
    fputs("No Data.\n",outfile);
    exit(1);
  }

  sock.encode();
  if (!sock.code(QueryType) ||
      !sock.code(FromDate) ||
      !sock.code(ToDate) ||
      !sock.code(Options) ||
      !sock.code(LinePtr) ||
      !sock.end_of_message()) {
    fprintf(stderr, "failed to send query to the CondorView server\n");
    fputs("No Data.\n",outfile);
    exit(1);
  }

  char NewStr[200];

  sock.decode();
  while(1) {
    if (!sock.code(LinePtr)) {
      fprintf(stderr, "failed to receive data from the CondorView server\n");
      if (LineCount==0) fputs("No Data.\n",outfile);
      exit(1);
    }
    if (strlen(LinePtr)==0) break;
    LineCount++;
    if (Options==0 && QueryType==QUERY_HIST_STARTD) {
      ResConvStr(LinePtr,NewStr);
      fputs(NewStr,outfile);
    }
    else {
      fputs(LinePtr,outfile);
    }
  }
  if (!sock.end_of_message()) {
    fprintf(stderr, "failed to receive data from the CondorView server\n");
  }

  if (LineCount==0) fputs("No Data.\n",outfile);
  if (FileName.Length()>0) fclose(outfile);

  return 0;
}

int CalcTime(int month, int day, int year) {
  struct tm time_str;
  if (year>1900) year-=1900;
  time_str.tm_year=year;
  time_str.tm_mon=month-1;
  time_str.tm_mday=day;
  time_str.tm_hour=0;
  time_str.tm_min=0;
  time_str.tm_sec=0;
  time_str.tm_isdst=-1;
  return mktime(&time_str);
}

int TimeLine(const MyString& TimeFileName,int FromDate, int ToDate, int Res)
{
  double Interval=double(ToDate-FromDate)/double(Res);
  float RelT;
  time_t T;
  FILE* TimeFile=fopen(TimeFileName.Value(),"w");
  if (!TimeFile) return -1;
  for (int i=0; i<=Res; i++) {
    T=(time_t)FromDate+((int)Interval*i);
    RelT=float(100.0/Res)*i;
	fprintf(TimeFile,"%.2f\t%s",RelT,asctime(localtime(&T)));
  }
  fclose(TimeFile);
  return 0;
}
<|endoftext|>


<commit_before>AliESDtrackCuts *CreateCuts(Int_t iCut = 0); // create the standard cuts
AliAnalysisTaskESDfilter *AddTaskESDfilter(bool bUseKineFilter = true)
{
// Creates a jet fider task, configures it and adds it to the analysis manager.

   // Get the pointer to the existing analysis manager via the static access method.
   //==============================================================================
   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskESDFilter", "No analysis manager to connect to.");
      return NULL;
   }

   // Check the analysis type using the event handlers connected to the analysis manager.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskESDFilter", "This task requires an input event handler");
      return NULL;
   }

   // Check if MC handler is connected in case kine filter requested
   AliMCEventHandler *mcH = (AliMCEventHandler*)mgr->GetMCtruthEventHandler();
   if (!mcH && bUseKineFilter) {
     ::Error("AddTaskESDFilter", "No MC handler connected while kine filtering requested");
      return NULL;
   }

   // Create the task and configure it.
   //===========================================================================

   // this task is also needed to set the MCEventHandler
   // to the AODHandler, this will not be needed when
   // AODHandler goes to ANALYSISalice
   AliAnalysisTaskMCParticleFilter *kinefilter = 0;
   if (bUseKineFilter) {
      kinefilter = new AliAnalysisTaskMCParticleFilter("Particle Kine Filter");
      mgr->AddTask(kinefilter);
   }

   AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
   trackFilter->AddCuts(CreateCuts(0));

   AliAnalysisTaskESDfilter *esdfilter = new AliAnalysisTaskESDfilter("ESD Filter");
   esdfilter->SetTrackFilter(trackFilter);
   mgr->AddTask(esdfilter);

   // Create ONLY the output containers for the data produced by the task.
   // Get and connect other common input/output containers via the manager as below
   //==============================================================================
   mgr->ConnectInput  (esdfilter, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput (esdfilter, 0, mgr->GetCommonOutputContainer());

   if (bUseKineFilter) {
     mgr->ConnectInput  (kinefilter,  0, mgr->GetCommonInputContainer());
     mgr->ConnectOutput (kinefilter,  0, mgr->GetCommonOutputContainer());
   }

   return esdfilter;
}

AliESDtrackCuts *CreateCuts(Int_t iCut){
  AliESDtrackCuts* esdTrackCuts = 0;
  if(iCut == 0){
    esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts", "Loose");
    esdTrackCuts->SetMinNClustersTPC(50);
    esdTrackCuts->SetMaxChi2PerClusterTPC(3.5);
    esdTrackCuts->SetMaxCovDiagonalElements(2,2,0.5,0.5,2);
    esdTrackCuts->SetRequireTPCRefit(kTRUE);
    esdTrackCuts->SetMaxNsigmaToVertex(3);
    esdTrackCuts->SetRequireSigmaToVertex(kTRUE);
    esdTrackCuts->SetAcceptKingDaughters(kFALSE);
  }

  return esdTrackCuts;

}
<commit_msg>add output list<commit_after>AliESDtrackCuts *CreateCuts(Int_t iCut = 0); // create the standard cuts
AliAnalysisTaskESDfilter *AddTaskESDfilter(bool bUseKineFilter = true)
{
// Creates a jet fider task, configures it and adds it to the analysis manager.

   // Get the pointer to the existing analysis manager via the static access method.
   //==============================================================================
   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
   if (!mgr) {
      ::Error("AddTaskESDFilter", "No analysis manager to connect to.");
      return NULL;
   }

   // Check the analysis type using the event handlers connected to the analysis manager.
   //==============================================================================
   if (!mgr->GetInputEventHandler()) {
      ::Error("AddTaskESDFilter", "This task requires an input event handler");
      return NULL;
   }

   // Check if MC handler is connected in case kine filter requested
   AliMCEventHandler *mcH = (AliMCEventHandler*)mgr->GetMCtruthEventHandler();
   if (!mcH && bUseKineFilter) {
     ::Error("AddTaskESDFilter", "No MC handler connected while kine filtering requested");
      return NULL;
   }

   // Create the task and configure it.
   //===========================================================================

   // this task is also needed to set the MCEventHandler
   // to the AODHandler, this will not be needed when
   // AODHandler goes to ANALYSISalice
   AliAnalysisTaskMCParticleFilter *kinefilter = 0;
   if (bUseKineFilter) {
      kinefilter = new AliAnalysisTaskMCParticleFilter("Particle Kine Filter");
      mgr->AddTask(kinefilter);
   }

   AliAnalysisFilter* trackFilter = new AliAnalysisFilter("trackFilter");
   trackFilter->AddCuts(CreateCuts(0));

   AliAnalysisTaskESDfilter *esdfilter = new AliAnalysisTaskESDfilter("ESD Filter");
   esdfilter->SetTrackFilter(trackFilter);
   mgr->AddTask(esdfilter);

   // Create ONLY the output containers for the data produced by the task.
   // Get and connect other common input/output containers via the manager as below
   //==============================================================================
   mgr->ConnectInput  (esdfilter, 0, mgr->GetCommonInputContainer());
   mgr->ConnectOutput (esdfilter, 0, mgr->GetCommonOutputContainer());

   if (bUseKineFilter) {
     mgr->ConnectInput  (kinefilter,  0, mgr->GetCommonInputContainer());
     mgr->ConnectOutput (kinefilter,  0, mgr->GetCommonOutputContainer());
     AliAnalysisDataContainer *coutputEx = mgr->CreateContainer("cFilterList", TList::Class(),
								AliAnalysisManager::kOutputContainer,"pyxsec_hists.root");
     mgr->ConnectOutput (kinefilter,  1,coutputEx);
   }

   return esdfilter;
}

AliESDtrackCuts *CreateCuts(Int_t iCut){
  AliESDtrackCuts* esdTrackCuts = 0;
  if(iCut == 0){
    esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts", "Loose");
    esdTrackCuts->SetMinNClustersTPC(50);
    esdTrackCuts->SetMaxChi2PerClusterTPC(3.5);
    esdTrackCuts->SetMaxCovDiagonalElements(2,2,0.5,0.5,2);
    esdTrackCuts->SetRequireTPCRefit(kTRUE);
    esdTrackCuts->SetMaxNsigmaToVertex(3);
    esdTrackCuts->SetRequireSigmaToVertex(kTRUE);
    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
  }

  return esdTrackCuts;

}
<|endoftext|>


<commit_before>//
//  6502AllRAM.cpp
//  CLK
//
//  Created by Thomas Harte on 13/07/2015.
//  Copyright © 2015 Thomas Harte. All rights reserved.
//

#include "6502AllRAM.hpp"
#include <algorithm>
#include <string.h>

using namespace CPU::MOS6502;

AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {}

int AllRAMProcessor::perform_bus_operation(MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
	timestamp_++;

	if(isReadOperation(operation)) {
		*value = memory_[address];
	} else {
		memory_[address] = *value;
	}

	return 1;
}
<commit_msg>Restored the all RAM 6502's lack of power-on reset.<commit_after>//
//  6502AllRAM.cpp
//  CLK
//
//  Created by Thomas Harte on 13/07/2015.
//  Copyright © 2015 Thomas Harte. All rights reserved.
//

#include "6502AllRAM.hpp"
#include <algorithm>
#include <string.h>

using namespace CPU::MOS6502;

AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {
	set_power_on(false);
}

int AllRAMProcessor::perform_bus_operation(MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
	timestamp_++;

	if(isReadOperation(operation)) {
		*value = memory_[address];
	} else {
		memory_[address] = *value;
	}

	return 1;
}
<|endoftext|>


<commit_before>#ifndef IOD_JSON_HH_
# define IOD_JSON_HH_

#include <vector>
#include <fstream>
#include <cassert>
#include <tuple>
#include <string>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <map>
#include <boost/preprocessor/repetition/repeat.hpp>

#include <iod/sio.hh>
#include <iod/foreach.hh>
#include <iod/symbols.hh>

// Json IOD api.

namespace iod
{

  using namespace s;

  // Decode \o from a json string \str.
  template <typename ...T>
  inline void json_decode(sio<T...>& o, const std::string& str);

  // Encode \o into a json string.
  template <typename ...T>
  inline std::string json_encode(const sio<T...>& o);

  // Encode \o into a stream.
  template <typename S, typename ...Tail>
  inline void json_encode(const sio<Tail...>& o, S& stream);

  namespace json_internals
  {

    // Json encoder.
    // =============================================
    template <typename T, typename S>
    inline void json_encode_(const T& t, S& ss)
    {
      ss << t;
    }

    template <typename S>
    inline void json_encode_(const char* t, S& ss)
    {
      ss << '"' << t << '"';
    }

    template <typename S>
    inline void json_encode_(const std::string& t, S& ss)
    {
      json_encode_(t.c_str(), ss);
    }

    // Forward declaration.
    template <typename S, typename ...Tail>
    inline void json_encode_(const sio<Tail...>& o, S& ss);

    template <typename T, typename S>
    inline void json_encode_(const std::vector<T>& array, S& ss)
    {
      ss << '[';
      for (const auto& t : array)
      {
        json_encode_(t, ss);
        if (&t != &array.back())
          ss << ',';
      }
      ss << ']';
    }

    template <typename S, typename ...Tail>
    inline void json_encode_(const sio<Tail...>& o, S& ss)
    {
      ss << '{';
      int i = 0;
      foreach(o) | [&] (const auto& m)
      {
        json_encode_(m.attributes().get(_Json_symbol, m.symbol()).name(), ss);
        ss << ':';
        json_encode_(m.value(), ss);
        if (i != o.size() - 1) ss << ',';
        i++;
      };
      ss << '}';
    }

    // Json decoder.
    // =============================================

    template <typename T>
    struct fill_ {
      inline fill_(T& _r) : r(_r) {}
      T& r;
    };

    template <typename T>
    inline fill_<T> fill(T& t) { return fill_<T>(t); }

    struct json_parser
    {
      struct spaces_ {} spaces;

      inline json_parser(std::istringstream& _stream) : ss(_stream) {}

      inline char peak() { return ss.peek(); }
      inline char eof() { return ss.eof(); }

      template <typename E>
      inline void format_error(E& err) {}

      template <typename E, typename T1, typename... T>
      inline void format_error(E& err, T1 a, T... args)
      {
        err << a;
        format_error(err, args...);
      }

      template <typename... T>
      inline std::runtime_error json_error(T... message)
        {
          std::stringstream err;

          auto str = ss.str();
          int pos = ss.tellg();
          int w = 20;
          int b = pos > w ? pos - w : 0;
          int e = pos < int(str.size()) - w ? pos + w : int(str.size()) - 1;
          std::string near(str.begin() + b, str.begin() + e);
          err << std::endl << "Json parse error near " << near << std::endl;
          err << "                      ";
          for (int i = 0; i < pos - b - 1; i++) err << ' ';
          err << "^^^"<< std::endl;
          format_error(err, message...);
          // assert(0);
          return std::runtime_error(err.str());
        }

      inline json_parser& fill(std::string& t)
        {
          int start = ss.tellg();
          int end;
          char c, prev_c;
          auto str = ss.str();
          do
          {
            ss.ignore(1000, '"');
            end = ss.tellg();
            c = str[end];
            prev_c = str[end - 1];
          } while (c == '"' and prev_c != '\\');

          ss.unget();
          t.clear();
          t = str.substr(start, end - start - 1);
          return *this;
        }

      template <typename T>
      inline json_parser& fill(T&& t)
        {
          ss >> t;
          if (ss.good()) return *this;
          else
            throw json_error();
        }

      template <typename T>
      inline json_parser& operator>>(fill_<T>&& t)
        {
          return fill(t.r);
        }

      inline json_parser& operator>>(char t)
        {
          char value;
          do
          {
            ss.get(value);
          }
          while(value == ' ');

          if (ss.good() && value == t) return *this;
          else
          {
            throw json_error("Expected ", t, " got ", value);
          }
        }

      template <typename T>
      inline json_parser& operator>>(T t)
        {
          T value;
          ss >> value;
          if (ss.good() && value == t) return *this;
          else
          {
            throw json_error();
          }
        }

      inline json_parser& operator>>(const char* t)
        {
          std::string value;
          fill(value);
          if (ss.good() && value == std::string(t)) return *this;
          else
            throw json_error("Expected ", t, " got ", value);
        }

      inline json_parser& operator>>(spaces_)
        {
          char value;
          do
          {
            ss.get(value);
          }
          while(std::isspace(value));

          ss.unget();
          return *this;
        }

      int line_cpt, char_cpt;
      const char* cur;
      std::istringstream& ss;
    };

    inline void iod_attr_from_json(sio<>&, json_parser&)
    {
    }

    template <typename T>
    inline void iod_from_json_(T& t, json_parser& p)
    {
      p >> fill(t);
    }

    inline void iod_from_json_(std::string& t, json_parser& p)
    {
      p >> '"' >> fill(t) >> '"';
    }

    // Parse a json hashmap ordered the field in the object \o.
    template <typename T, typename ...Tail>
    inline void iod_attr_from_json_strict(sio<T, Tail...>& o, json_parser& p)
    {
      T* attr = &o;

      p >> p.spaces >> '"' >> attr->attribute_name() >> '"' >> p.spaces >> ':';

      iod_from_json_(attr->value(), p);
      if (sizeof...(Tail) != 0)
        p >> p.spaces >> ',';

      iod_attr_from_json(*static_cast<sio<Tail...>*>(&o), p);
    }

    // Parse a json hashmap.
    template <typename T, typename ...Tail>
    inline void iod_attr_from_json(sio<T, Tail...>& o, json_parser& p)
    {
      p >> p.spaces;

      std::map<std::string, bool> filled;
      std::map<std::string, int> symbol_map;
      int i = 0;
      foreach(o) | [&] (auto& m)
      {
        std::string name = m.symbol().name();
        if (m.attributes().has(_Json_symbol))
          name = m.attributes().get(_Json_symbol, _Json_symbol).name();
        symbol_map[name] = i++;
        filled[name] = false;
      };

      while (p.peak() != '}')
      {
        std::string attr_name;
        p >> p.spaces >> '"' >> fill(attr_name) >> '"' >> p.spaces >> ':' >> p.spaces;
        filled[attr_name] = true;
        auto it = symbol_map.find(attr_name);
        if (it != symbol_map.end())
        {
          switch (it->second)
          {
#define IOD_ATTR_CASE(z, I, X) case I: iod_from_json_(o.template get_nth<I>(), p); break;
            BOOST_PP_REPEAT(50, IOD_ATTR_CASE, x);
            #undef IOD_ATTR_CASE
          default:
            throw std::runtime_error(std::string("json_decode error: field does not exists: ") +
                                     it->first);
            break;
          }
        }
        p >> p.spaces;
        if (p.peak() == ',')
          p >> ',';
        else
          break;
      }

      if (p.peak() != '}')
      {
        throw p.json_error("Expected } got ", p.peak());
      }

      foreach(o) | [&] (auto& m) {
        typename std::remove_reference_t<decltype(m)>::attributes_type attrs;
        if (!m.attributes().has(_Optional) and !filled[m.symbol().name()])
          throw std::runtime_error(std::string("json_decode error: missing field ") +
                                   m.symbol().name());
      };
    }

    // Parse an array.
    template <typename T>
    inline void iod_from_json_(std::vector<T>& array, json_parser& p)
    {
      p >> '[' >> p.spaces;
      if (p.peak() == ']')
      {
        p >> ']';
        return;
      }

      array.clear();
      while (p.peak() != ']')
      {
        T t;
        iod_from_json_(t, p);
        array.push_back(t);
        p >> p.spaces;
        if (p.peak() == ']')
          break;
        else
          p >> ',';
      }

      p >> ']';
    }

    template <typename ...Tail>
    inline void iod_from_json_(sio<Tail...>& o, json_parser& p)
    {
      p >> p.spaces >> '{';
      iod_attr_from_json(o, p);
      p >> p.spaces >> '}';
    }

    template <typename ...Tail>
    inline void iod_from_json_(sio<Tail...>& o, const std::string& str)
    {
      std::istringstream stream(str);
      json_parser p(stream);
      if (str.size() > 0)
        iod_from_json_(o, p);
      else
        throw std::runtime_error("Empty string.");
    }
  }

  template <typename ...Tail>
  inline void json_decode(sio<Tail...>& o, const std::string& str)
  {
    json_internals::iod_from_json_(o, str);
  }

  template <typename ...Tail>
  inline void json_decode(sio<Tail...>& o, const std::string& str, int& n_read)
  {
    std::istringstream stream(str);
    json_internals::json_parser p(stream);
    if (str.size() > 0)
      iod_from_json_(o, p);
    else
      throw std::runtime_error("Empty string.");
    n_read = p.ss.tellg();
  }

  template <typename ...Tail>
  inline void json_decode(sio<Tail...>& o, std::istringstream& stream)
  {
    json_internals::json_parser p(stream);
    if (stream.str().size() > 0)
      iod_from_json_(o, p);
    else
      throw std::runtime_error("Empty string.");
  }

  template <typename ...Tail>
  inline std::string json_encode(const sio<Tail...>& o)
  {
    std::stringstream ss;
    json_internals::json_encode_(o, ss);
    return ss.str();
  }

  template <typename S, typename ...Tail>
  inline void json_encode(const sio<Tail...>& o, S& stream)
  {
    json_internals::json_encode_(o, stream);
  }

}

#endif
<commit_msg>x40 speedup on the json parser.<commit_after>#ifndef IOD_JSON_HH_
# define IOD_JSON_HH_

#include <vector>
#include <fstream>
#include <cassert>
#include <tuple>
#include <string>
#include <sstream>
#include <iostream>
#include <stdexcept>
#include <map>
#include <unordered_map>
#include <boost/lexical_cast.hpp>

#include <iod/sio.hh>
#include <iod/foreach.hh>
#include <iod/symbols.hh>
#include <iod/pow_10.hh>

// Json IOD api.

namespace iod
{

  using namespace s;

  // Decode \o from a json string \str.
  template <typename ...T>
  inline void json_decode(sio<T...>& o, const std::string& str);

  // Encode \o into a json string.
  template <typename ...T>
  inline std::string json_encode(const sio<T...>& o);

  // Encode \o into a stream.
  template <typename S, typename ...Tail>
  inline void json_encode(const sio<Tail...>& o, S& stream);

  namespace json_internals
  {

    struct stringview
    {
      stringview() {}
      stringview(const std::string& _str) : str(&_str[0]), len(_str.size()) {}
      stringview(const char* _str, int _len) : str(_str), len(_len) {}
      stringview(const char* _str) : str(_str), len(strlen(_str)) {}

      bool operator==(const stringview& o) const { return len == o.len and !strncmp(o.str, str, len); }
      bool operator==(const std::string& o) const { return len == o.size() and !strncmp(&o[0], str, len); }
      bool operator==(const char* o) const { return len == strlen(o) and !strncmp(o, str, len); }

      bool operator<(const stringview& o) const { return strncmp(o.str, str, std::min(len, o.len)); }
      explicit operator std::string() const { return std::string(str, len); }

      const char* str;
      int len;
    };

    // Json encoder.
    // =============================================
    template <typename T, typename S>
    inline void json_encode_(const T& t, S& ss)
    {
      ss << t;
    }

    template <typename S>
    inline void json_encode_(const char* t, S& ss)
    {
      ss << '"' << t << '"';
    }

    template <typename S>
    inline void json_encode_(const std::string& t, S& ss)
    {
      json_encode_(t.c_str(), ss);
    }

    // Forward declaration.
    template <typename S, typename ...Tail>
    inline void json_encode_(const sio<Tail...>& o, S& ss);

    template <typename T, typename S>
    inline void json_encode_(const std::vector<T>& array, S& ss)
    {
      ss << '[';
      for (const auto& t : array)
      {
        json_encode_(t, ss);
        if (&t != &array.back())
          ss << ',';
      }
      ss << ']';
    }

    template <typename S, typename ...Tail>
    inline void json_encode_(const sio<Tail...>& o, S& ss)
    {
      ss << '{';
      int i = 0;
      foreach(o) | [&] (const auto& m)
      {
        json_encode_(m.attributes().get(_Json_symbol, m.symbol()).name(), ss);
        ss << ':';
        json_encode_(m.value(), ss);
        if (i != o.size() - 1) ss << ',';
        i++;
      };
      ss << '}';
    }

    // Json decoder.
    // =============================================

    template <typename T>
    struct fill_ {
      inline fill_(T& _r) : r(_r) {}
      T& r;
    };

    template <typename T>
    inline fill_<T> fill(T& t) { return fill_<T>(t); }

    struct json_parser
    {
      struct spaces_ {} spaces;

      inline json_parser(std::istringstream& _stream) : str(_stream.str()), pos(0) {}
      inline json_parser(const std::string& _str) : str(_str), pos(0) {}

      inline char peak() { return str[pos]; }
      inline char eof() { return pos == str.size(); }
      inline char eat_one() { return pos++; }

      template <typename E>
      inline void format_error(E& err) {}

      template <typename E, typename T1, typename... T>
      inline void format_error(E& err, T1 a, T... args)
      {
        err << a;
        format_error(err, args...);
      }

      // inline void skip_spaces(spaces_) { while (!eof() and std::isspace(str[pos])) pos++; }

      template <typename... T>
      inline std::runtime_error json_error(T... message)
        {
          std::stringstream err;

          int w = 20;
          int b = pos > w ? pos - w : 0;
          int e = pos < int(str.size()) - w ? pos + w : int(str.size()) - 1;
          std::string near(str.begin() + b, str.begin() + e);
          err << std::endl << "Json parse error near " << near << std::endl;
          err << "                      ";
          for (int i = 0; i < pos - b - 1; i++) err << ' ';
          err << "^^^"<< std::endl;
          format_error(err, message...);
          return std::runtime_error(err.str());
        }

      inline json_parser& fill(std::string& t)
        {
          int start = pos;
          int end = pos + 1;

          while (!eof() and str[end] != '"') end++;
          t = str.substr(start, end - start);
          pos = end;
          return *this;
        }

      inline json_parser& fill(stringview& t)
        {
          int start = pos;
          int end = pos + 1;

          while (!eof() and str[end] != '"') end++;
          t.str = str.data() + start;
          t.len = end - start;
          pos = end;
          return *this;
        }

      template <typename I, int N>
      inline json_parser& fill_int(I& val)
        {
          int sign = 1;
          if (std::is_signed<I>::value and str[pos] == '-') { sign = -1; eat_one(); }
          else if (str[pos] == '+') { eat_one(); }

          int end = pos;

          val = 0;

          const char* s = str.data() + pos;

          for (int i = 0; i < N; i++)
          {
            val = val * 10 + (s[i] - '0');
            end++;
            if (s[i + 1] < '0' or s[i + 1] > '9') break;
          }
          val *= sign;

          pos = end;
          return *this;
        }

      inline json_parser& fill(float& val)
        {
          int end = pos;
          float res = 0;

          int ent = 0;
          fill_int<int, 10>(ent);

          res = ent;

          if (str[pos] == '.')
          {
            eat_one();
            unsigned int floating = 0;
            int start = pos;
            fill_int<unsigned int, 10>(floating);
            int end = pos;
            res += float(floating) / pow_10(end - start);
          }

          if (str[pos] == 'e')
          {
            eat_one();
            int exp = 0;
            fill_int<int, 10>(exp);
            res *= pow_10(exp);
          }

          val = res;
          return *this;
        }

      inline json_parser& fill(int& val) { return fill_int<int, 10>(val); }
      inline json_parser& fill(unsigned int& val) { return fill_int<unsigned int, 10>(val); }

      template <typename T>
      inline json_parser& fill(T& t)
        {
          int end = pos;
          while(!eof() and str[end] != ',' and str[end] != '}' and str[end] != ']') end++;
          t = boost::lexical_cast<std::remove_reference_t<T>>(str.data() + pos, end - pos);
          pos = end;
          return *this;
        }

      template <typename T>
      inline json_parser& operator>>(fill_<T>&& t)
        {
          return fill(t.r);
        }

      inline json_parser& operator>>(char t)
        {
          if (!eof() and str[pos] == t)
          {
            pos++;
            return *this;
          }
          else
          {
            if (eof())
              throw json_error("Expected ", t, " got eof");
            else
              throw json_error("Expected ", t, " got ", str[pos]);
          }
        }

      inline json_parser& operator>>(const char* t)
        {
          int start = pos;
          int end = pos;
          while (!eof() and (t[end - start] == str[end] or str[end] != '"')) end++;

          if (t[end - start] == '\0')
          {
            pos = end;
            return *this;
          }
          else
            throw json_error("Expected ", t, " got something else.");
        }

      inline json_parser& operator>>(spaces_)
        {
          while (!eof() and std::isspace(str[pos])) pos++;
          return *this;
        }

      int line_cpt, char_cpt;
      const char* cur;
      const std::string& str;
      int pos;
    };

    inline void iod_attr_from_json(sio<>&, json_parser&)
    {
    }

    template <typename T>
    inline void iod_from_json_(T& t, json_parser& p)
    {
      p >> fill(t);
    }

    inline void iod_from_json_(std::string& t, json_parser& p)
    {
      p >> '"' >> fill(t) >> '"';
    }

    // Parse a json hashmap ordered the field in the object \o.
    template <typename T, typename ...Tail>
    inline void iod_attr_from_json_strict(sio<T, Tail...>& o, json_parser& p)
    {
      T* attr = &o;

      p >> p.spaces >> '"' >> attr->symbol().name() >> '"' >> p.spaces >> ':';

      iod_from_json_(attr->value(), p);
      if (sizeof...(Tail) != 0)
        p >> p.spaces >> ',';

      iod_attr_from_json(*static_cast<sio<Tail...>*>(&o), p);
    }

    // Parse a json hashmap.
    template <typename T, typename ...Tail>
    inline void iod_attr_from_json(sio<T, Tail...>& o, json_parser& p)
    {
      p >> p.spaces;

      struct attr_info { bool filled; stringview name; };

      attr_info A[std::remove_reference_t<decltype(o)>::size()];

      int i = 0;
      foreach(o) | [&] (auto& m)
      {
        A[i].filled = false;
        stringview name(m.symbol().name(), strlen(m.symbol().name()));
        if (m.attributes().has(_Json_symbol))
        {
          const char* new_name = m.attributes().get(_Json_symbol, _Json_symbol).name();
          name = stringview(new_name, strlen(new_name));
        }
        A[i].name = name;
        i++;
      };

      while (p.peak() != '}')
      {
        stringview attr_name;
        p >> p.spaces >> '"' >> fill(attr_name) >> '"' >> p.spaces >> ':' >> p.spaces;

        int i = 0;
        foreach(o) | [&] (auto& m)
        {
          if (attr_name == A[i].name) { iod_from_json_(m.value(), p); A[i].filled = true; }
          i++;
        };

        p >> p.spaces;
        if (p.peak() == ',')
          p.eat_one();
        else
          break;
      }

      if (p.peak() != '}')
      {
        throw p.json_error("Expected } got ", p.peak());
      }

      i = 0;
      foreach(o) | [&] (auto& m) {
        typename std::remove_reference_t<decltype(m)>::attributes_type attrs;
        if (!m.attributes().has(_Optional) and !A[i].filled)
          throw std::runtime_error(std::string("json_decode error: missing field ") +
                                   m.symbol().name());
        i++;
      };
    }

    // Parse an array.
    template <typename T>
    inline void iod_from_json_(std::vector<T>& array, json_parser& p)
    {
      p >> '[' >> p.spaces;
      if (p.peak() == ']')
      {
        p >> ']';
        return;
      }

      array.clear();
      while (p.peak() != ']')
      {
        T t;
        iod_from_json_(t, p);
        array.push_back(t);
        p >> p.spaces;
        if (p.peak() == ']')
          break;
        else
          p >> ',';
      }

      p >> ']';
    }

    template <typename ...Tail>
    inline void iod_from_json_(sio<Tail...>& o, json_parser& p)
    {
      p >> p.spaces >> '{';
      iod_attr_from_json(o, p);
      p >> p.spaces >> '}';
    }

    template <typename ...Tail>
    inline void iod_from_json_(sio<Tail...>& o, const std::string& str)
    {
      json_parser p(str);
      if (str.size() > 0)
        iod_from_json_(o, p);
      else
        throw std::runtime_error("Empty string.");
    }
  }

  template <typename ...Tail>
  inline void json_decode(sio<Tail...>& o, const std::string& str)
  {
    json_internals::iod_from_json_(o, str);
  }

  template <typename ...Tail>
  inline void json_decode(sio<Tail...>& o, const std::string& str, int& n_read)
  {
    std::istringstream stream(str);
    json_internals::json_parser p(stream);
    if (str.size() > 0)
      iod_from_json_(o, p);
    else
      throw std::runtime_error("Empty string.");
    n_read = p.pos;
  }

  template <typename ...Tail>
  inline void json_decode(sio<Tail...>& o, std::istringstream& stream)
  {
    json_internals::json_parser p(stream);
    if (stream.str().size() > 0)
      iod_from_json_(o, p);
    else
      throw std::runtime_error("Empty string.");
  }

  template <typename ...Tail>
  inline std::string json_encode(const sio<Tail...>& o)
  {
    std::stringstream ss;
    json_internals::json_encode_(o, ss);
    return ss.str();
  }

  template <typename S, typename ...Tail>
  inline void json_encode(const sio<Tail...>& o, S& stream)
  {
    json_internals::json_encode_(o, stream);
  }

}

#endif
<|endoftext|>


<commit_before>#include "die-tk.h"
#include "die-tk-image/convert.h"
#include <iostream>
#include <string>
using namespace std::literals::string_literals;

namespace {

#ifdef BAZEL_FOR_WINDOWS
std::string baseDir = "../../../../../../"s;
#else
std::string baseDir = "";
#endif

// from data dir dependency. see how to relocate it
std::string imageDir = baseDir + "examples/imageLoad/"s;

}

using namespace tk;

int main()
{
	Application app;

	Window window(WindowParams("test image load and transparency!").dims({700,400}));

	auto boss = convertImage(img::Image(imageDir + "boss.png"));
	auto diego = convertImage(img::Image(imageDir + "DIEGO1.jpg"));
	auto explosion = convertImage(img::Image(imageDir + "explosion0.png"));
	auto explosion3 = convertImage(img::Image(imageDir + "explosion3.png"));
	auto bugLeft = convertImage(img::Image(imageDir + "bugLeft.png"));
	auto gameTitle = convertImage(img::Image(imageDir + "gameTitle.png"));
	window.onPaint([&](Canvas & canvas, Rect) {
		canvas.drawImage(diego,Point(0,0));
		canvas.drawImage(explosion,Point(5,5));
		canvas.drawImage(explosion3,Point(80,5));
		canvas.drawImage(boss,Point(20,100));
		canvas.drawImage(bugLeft,Point(300,15));
		canvas.drawImage(gameTitle,Point(300,40));
	});

	PaintBox p(window, ControlParams().start({5,40}).dims({40,40}));
	p.onPaint([&](Canvas & canvas, Rect rect) {
		std::cout << rect << std::endl;
		canvas.fillRect(Rect::open(Point(2,2),WDims(6,6)),RGBColor(100,0,0));
		canvas.drawImage(explosion,Point(0,0));
		// TODO X11 copy rect into fails with smaller rectangles
		// TODO X11 PaintBox transparency fails
		//explosion->copyRectInto(canvas,rect,rect.topLeft());
	});
	std::cout << p.rect() << std::endl;

	// TODO remove this ifdef after implementing image in X11
#ifdef WIN32
	// TODO make Image support transparent images - it is cloneBitmap()'s fault
	Image i(window, ControlParams().start(p.pos().addY(32)).autosize());
	i.setImage(explosion);
	Image j = i.clone();
	j.setBackground(RGBColor(120,0,0));
	j.setPos(i.pos().addX(32));
	j.setDims(WDims(40,40));
#endif

	do {
		app.waitForMessages();
		app.processMessages();
	} while( window.visible() );
}
<commit_msg>build<commit_after>#include "die-tk.h"
#include "die-tk-image/convert.h"
#include <iostream>
#include <string>
using namespace std::literals::string_literals;

namespace {

#ifdef BAZEL_FOR_WINDOWS
std::string imageDir = "../../../../../../examples/imageLoad/"s;
#else
std::string imageDir = "";
#endif

}

using namespace tk;

int main()
{
	Application app;

	Window window(WindowParams("test image load and transparency!").dims({700,400}));

	auto boss = convertImage(img::Image(imageDir + "boss.png"));
	auto diego = convertImage(img::Image(imageDir + "DIEGO1.jpg"));
	auto explosion = convertImage(img::Image(imageDir + "explosion0.png"));
	auto explosion3 = convertImage(img::Image(imageDir + "explosion3.png"));
	auto bugLeft = convertImage(img::Image(imageDir + "bugLeft.png"));
	auto gameTitle = convertImage(img::Image(imageDir + "gameTitle.png"));
	window.onPaint([&](Canvas & canvas, Rect) {
		canvas.drawImage(diego,Point(0,0));
		canvas.drawImage(explosion,Point(5,5));
		canvas.drawImage(explosion3,Point(80,5));
		canvas.drawImage(boss,Point(20,100));
		canvas.drawImage(bugLeft,Point(300,15));
		canvas.drawImage(gameTitle,Point(300,40));
	});

	PaintBox p(window, ControlParams().start({5,40}).dims({40,40}));
	p.onPaint([&](Canvas & canvas, Rect rect) {
		std::cout << rect << std::endl;
		canvas.fillRect(Rect::open(Point(2,2),WDims(6,6)),RGBColor(100,0,0));
		canvas.drawImage(explosion,Point(0,0));
		// TODO X11 copy rect into fails with smaller rectangles
		// TODO X11 PaintBox transparency fails
		//explosion->copyRectInto(canvas,rect,rect.topLeft());
	});
	std::cout << p.rect() << std::endl;

	// TODO remove this ifdef after implementing image in X11
#ifdef WIN32
	// TODO make Image support transparent images - it is cloneBitmap()'s fault
	Image i(window, ControlParams().start(p.pos().addY(32)).autosize());
	i.setImage(explosion);
	Image j = i.clone();
	j.setBackground(RGBColor(120,0,0));
	j.setPos(i.pos().addX(32));
	j.setDims(WDims(40,40));
#endif

	do {
		app.waitForMessages();
		app.processMessages();
	} while( window.visible() );
}
<|endoftext|>


<commit_before><commit_msg>VM: differenciate the 'not loaded' error<commit_after><|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSurfaceToPointSetFilter.h"

// mitk headers
#include "mitkPointSet.h"

// itk headers
#include "itkMatrix.h"
#include "itkVector.h"

// vtk headers
#include <vtkCleanPolyData.h>
#include <vtkPolyData.h>

mitk::SurfaceToPointSetFilter::SurfaceToPointSetFilter()
{
  this->SetNumberOfOutputs(1);
}

mitk::SurfaceToPointSetFilter::~SurfaceToPointSetFilter()
{
}

void mitk::SurfaceToPointSetFilter::GenerateData()
{
  if (m_InputSurface.IsNull())
  {
    this->SetNthOutput(0, nullptr);
    m_ErrorMessage = "Error in SurfaceToPointSetFilter: Input is not set correctly.";
    return;
  }
  mitk::PointSet::Pointer result = mitk::PointSet::New();

  vtkPolyData *points = this->m_InputSurface->GetVtkPolyData();
  vtkCleanPolyData *cleaner = vtkCleanPolyData::New();
  cleaner->PieceInvariantOff();
  cleaner->ConvertLinesToPointsOff();
  cleaner->ConvertPolysToLinesOff();
  cleaner->ConvertStripsToPolysOff();
  cleaner->PointMergingOn();
  cleaner->SetInputData(points);
  cleaner->Update();

  vtkPolyData *mergedPoints = cleaner->GetOutput();

  // generate filter output
  for (int i = 0; i < mergedPoints->GetNumberOfPoints(); i++)
  {
    mitk::Point3D currentPoint;
    currentPoint[0] = mergedPoints->GetPoint(i)[0];
    currentPoint[1] = mergedPoints->GetPoint(i)[1];
    currentPoint[2] = mergedPoints->GetPoint(i)[2];
    result->InsertPoint(i, currentPoint);
  }
  this->SetNthOutput(0, result);
  //-------------------------

  cleaner->Delete();
}

void mitk::SurfaceToPointSetFilter::SetInput(mitk::Surface::Pointer InputSurface)
{
  m_InputSurface = InputSurface;
  this->Modified();
}

std::string mitk::SurfaceToPointSetFilter::GetErrorMessage()
{
  return this->m_ErrorMessage;
}
<commit_msg>Fix warnings in imaging example plugin<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkSurfaceToPointSetFilter.h"

// mitk headers
#include "mitkPointSet.h"

// itk headers
#include "itkMatrix.h"
#include "itkVector.h"

// vtk headers
#include <vtkCleanPolyData.h>
#include <vtkPolyData.h>

mitk::SurfaceToPointSetFilter::SurfaceToPointSetFilter()
{
  this->SetNumberOfIndexedOutputs(1);
}

mitk::SurfaceToPointSetFilter::~SurfaceToPointSetFilter()
{
}

void mitk::SurfaceToPointSetFilter::GenerateData()
{
  if (m_InputSurface.IsNull())
  {
    this->SetNthOutput(0, nullptr);
    m_ErrorMessage = "Error in SurfaceToPointSetFilter: Input is not set correctly.";
    return;
  }
  mitk::PointSet::Pointer result = mitk::PointSet::New();

  vtkPolyData *points = this->m_InputSurface->GetVtkPolyData();
  vtkCleanPolyData *cleaner = vtkCleanPolyData::New();
  cleaner->PieceInvariantOff();
  cleaner->ConvertLinesToPointsOff();
  cleaner->ConvertPolysToLinesOff();
  cleaner->ConvertStripsToPolysOff();
  cleaner->PointMergingOn();
  cleaner->SetInputData(points);
  cleaner->Update();

  vtkPolyData *mergedPoints = cleaner->GetOutput();

  // generate filter output
  for (int i = 0; i < mergedPoints->GetNumberOfPoints(); i++)
  {
    mitk::Point3D currentPoint;
    currentPoint[0] = mergedPoints->GetPoint(i)[0];
    currentPoint[1] = mergedPoints->GetPoint(i)[1];
    currentPoint[2] = mergedPoints->GetPoint(i)[2];
    result->InsertPoint(i, currentPoint);
  }
  this->SetNthOutput(0, result);
  //-------------------------

  cleaner->Delete();
}

void mitk::SurfaceToPointSetFilter::SetInput(mitk::Surface::Pointer InputSurface)
{
  m_InputSurface = InputSurface;
  this->Modified();
}

std::string mitk::SurfaceToPointSetFilter::GetErrorMessage()
{
  return this->m_ErrorMessage;
}
<|endoftext|>


<commit_before><commit_msg>Still drifting<commit_after><|endoftext|>


<commit_before>#include "gmock/gmock.h"
#include "Computer.h"

using namespace testing;
using namespace std;

TEST(ComputerAI, ComputerWins) {
}
<commit_msg>AI test<commit_after>#include "gmock/gmock.h"
#include "Computer.h"
#include "Human.h"
#include "Board.h"

using namespace testing;
using namespace std;

class AI: public Test {
    public:
        Board board;
		Human human;
		Computer ai;
};

TEST_F(AI, ComputerMakeMoveToWin) {
	human.setCallSign(PlayerOptions::X);
	ai.setCallSign(PlayerOptions::O);
	board.makeMove(ai,0);
	board.makeMove(ai,1);
	ASSERT_THAT(ai.calculateMove(board), Eq(2));
}
<|endoftext|>


<commit_before>#include <siplasplas/cmake/project.hpp>
#include <iostream>

using namespace cpp;

class CMakeProgress : public cpp::SignalEmitter
{
public:
    void onBuildStarted(const std::string& target)
    {
        std::cout << "Building " << target << "...\n";
    }

    void onBuildFinished(const std::string& target, bool successful)
    {
        if(successful)
        {
            std::cout << target << " successfully built.\n";
        }
        else
        {
            std::cout << target << " build failed.\n";
        }
    }

    void stdoutLineFromBuildJob(const std::string& line)
    {
        std::cout << line << "\n";
    }
};

int main()
{
    CMakeProject project(CMAKE_SOURCE_DIR, CMAKE_BINARY_DIR);
    CMakeProgress cmakeProgress;

    project.watchTarget("examples-reflection", CMAKE_SOURCE_DIR "/examples/reflection");

    SignalEmitter::connect_async(project, &CMakeProject::buildStarted, cmakeProgress, &CMakeProgress::onBuildStarted);
    SignalEmitter::connect_async(project, &CMakeProject::buildFinished, cmakeProgress, &CMakeProgress::onBuildFinished);
    SignalEmitter::connect_async(project, &CMakeProject::stdoutLine, cmakeProgress, &CMakeProgress::stdoutLineFromBuildJob);

    project.startWatch();

    while(true)
    {
        cmakeProgress.poll();
    }
}
<commit_msg>CMake lib example rebuilds and runs reflection example<commit_after>#include <siplasplas/cmake/project.hpp>
#include <iostream>

using namespace cpp;

class CMakeProgress : public cpp::SignalEmitter
{
public:
    void onBuildStarted(const std::string& target)
    {
        std::cout << "Building " << target << "...\n";
    }

    void onBuildFinished(const std::string& target, bool successful)
    {
        if(successful)
        {
            std::cout << target << " successfully built.\n";
        }
        else
        {
            std::cout << target << " build failed.\n";
        }
    }

    void stdoutLineFromBuildJob(const std::string& line)
    {
        std::cout << line << "\n";
    }
};

int main()
{
    CMakeProject project(CMAKE_SOURCE_DIR, CMAKE_BINARY_DIR);
    CMakeProgress cmakeProgress;

    project.watchTarget("run-examples-reflection", CMAKE_SOURCE_DIR "/examples/reflection");

    SignalEmitter::connect_async(project, &CMakeProject::buildStarted, cmakeProgress, &CMakeProgress::onBuildStarted);
    SignalEmitter::connect_async(project, &CMakeProject::buildFinished, cmakeProgress, &CMakeProgress::onBuildFinished);
    SignalEmitter::connect_async(project, &CMakeProject::stdoutLine, cmakeProgress, &CMakeProgress::stdoutLineFromBuildJob);

    project.startWatch();

    while(true)
    {
        cmakeProgress.poll();
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix RenderWidget::resizeEvent()<commit_after><|endoftext|>