<commit_before>/****************************************************************************
** irsimsend.c *************************************************************
****************************************************************************
*
* irsimsend - send all codes defined in a given config file.
*
*/

#include <config.h>

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <getopt.h>

#include "lirc_private.h"
#include "lirc_client.h"

static const logchannel_t logchannel = LOG_APP;

static const char* const USAGE =
	"Send key symbols durations to fixed file 'simsend.out'.\n\n"
	"Synopsis:\n"
	"    irsimsend [-U path] [-s time] [-c count] <file>\n"
	"    irsimsend [-k keysym | -l listfile] [-U path] [-s time] [-c count]"
	" <file>\n"
	"    irsimsend [-h | -v]\n\n"
	"<file> is a lircd.conf type config file. In the first form, all keys in\n"
	"that file are sent.\n\n"
	"Options:\n"
	"    -U, --plugindir <path>:     Load drivers from <path>.\n"
	"    -c, --config <count>:       Repeat each key <count> times.\n"
	"    -l, --listfile <file>       Send symbols in file.\n"
	"    -k, --keysym <keysym>       Send a single keysym.\n"
	"    -s, --start-space <time>    Send a start space <time> us\n"
	"    -v, --version               Print version.\n"
	"    -h, --help                  Print this message.\n";

static struct option options[] = {
	{ "help",	 no_argument,	    NULL, 'h' },
	{ "version",	 no_argument,	    NULL, 'v' },
	{ "count",	 required_argument, NULL, 'c' },
	{ "keysym",	 required_argument, NULL, 'k' },
	{ "listfile",	 required_argument, NULL, 'l' },
	{ "pluginpath",	 required_argument, NULL, 'U' },
	{ "start-space", required_argument, NULL, 's' },
	{ 0,		 0,		    0,	  0   }
};

static const char* const OUTFILE = "simsend.out";

static int opt_count = 1;
static int opt_startspace = -1;
static const char* opt_keysym = NULL;
static const char* opt_listfile = NULL;

/** Set up default values for all command line options + filename. */
static void add_defaults(void)
{
	static char plugindir[128];
	const char* defaults[] = {
		"lircd:plugindir",	      plugindir,
		"irsimsend:driver",	      "devinput",
		"irsimsend:count",	      "1",
		"irsimsend:keysym",	      (const char*)NULL,
		"irsimsend:listfile",	      (const char*)NULL,
		"irsimsend:start-space"	      "-1",
		(const char*)NULL,	      (const char*)NULL
	};
	const char* s = getenv("LIRC_PLUGIN_PATH");

	strncpy(plugindir, s != NULL ? s : PLUGINDIR, sizeof(plugindir) - 1);
	options_add_defaults(defaults);
};

int parse_uint_arg(const char* optind, const char* errmsg)
{
	long c;

	c = strtol(optarg, NULL, 10);
	if (c > INT_MAX || c < 0 || errno == EINVAL || errno == ERANGE) {
		fputs(errmsg, stderr);
		exit(EXIT_FAILURE);
	}
	return (int)c;
}

static void parse_options(int argc, char** const argv)
{
	long c;

	add_defaults();

	while ((c = getopt_long(argc, argv, "c:hk:l:s:U:v", options, NULL))
	       != EOF) {
		switch (c) {
		case 'h':
			puts(USAGE);
			exit(EXIT_SUCCESS);
		case 'c':
			(void) parse_uint_arg(optarg, "Illegal count value\n");
			options_set_opt("irsimsend:count", optarg);
			break;
		case 'v':
			printf("%s\n", "irw " VERSION);
			exit(EXIT_SUCCESS);
		case 'U':
			options_set_opt("lircd:plugindir", optarg);
			break;
		case 'k':
			options_set_opt("irsimsend:keysym", optarg);
			break;
		case 'l':
			options_set_opt("irsimsend:listfile", optarg);
			break;
		case 's':
			(void) parse_uint_arg(optarg, "Illegal space value\n");
			options_set_opt("irsimsend:start-space", optarg);
			break;
		case '?':
			fprintf(stderr, "unrecognized option: -%c\n", optopt);
			fputs("Try `irsimsend -h' for more information.\n",
			      stderr);
			exit(EXIT_FAILURE);
		}
	}
	if (argc != optind + 1) {
		fputs(USAGE, stderr);
		exit(EXIT_FAILURE);
	}
}

static struct ir_remote* setup(const char* path)
{
	struct ir_remote* remote;
	FILE* f;

	if (hw_choose_driver("file") == -1) {
		fputs("Cannot load file driver (bad plugin path?)\n",
		      stderr);
		exit(EXIT_FAILURE);
	}
	unlink(OUTFILE);
	curr_driver->open_func(OUTFILE);
	curr_driver->init_func();

	if (opt_listfile != NULL && access(opt_listfile, R_OK) != 0) {
		fprintf(stderr, "Cannot open %s for read\n", opt_listfile);
		exit(EXIT_FAILURE);
	}
	f = fopen(path, "r");
	if (f == NULL) {
		fprintf(stderr, "Cannot open %s for read\n", path);
		exit(EXIT_FAILURE);
	}
	remote = read_config(f, path);
	fclose(f);
	if (remote == NULL) {
		fprintf(stderr, "Cannot parse %s\n", path);
		exit(EXIT_FAILURE);
	}
	remote->min_repeat = 0;
	return remote;
}

static void send_space(int duration)
{
	char buff[64];

	snprintf(buff, sizeof(buff), "send-space:%d", duration);
	drv_handle_options(buff);
}

static void send_code(struct ir_remote* remote, struct ir_ncode* code)
{
	int i;
	static char last_code[32] = { '\0' };

	code->transmit_state = NULL;
	if (has_toggle_mask(remote))
		remote->toggle_mask_state = 0;
	if (has_toggle_bit_mask(remote))
		remote->toggle_bit_mask_state =
			(remote->toggle_bit_mask_state ^ remote->toggle_bit_mask);
	code->transmit_state = NULL;
	remote->min_repeat = 0;
	if (strcmp(code->name, last_code) == 0)
		repeat_remote = remote;
	send_ir_ncode(remote, code, 0);
	repeat_remote = remote;
	for (i = 1; i < opt_count; i += 1)
		send_ir_ncode(remote, code, 0);
	repeat_remote = NULL;
	strncpy(last_code, code->name, sizeof(last_code));
}

static int simsend_remote(struct ir_remote* remote)
{
	struct ir_ncode* code;

	while (remote != NULL) {
		for (code = remote->codes; code->name != NULL; code++) {
			printf("%s\n", code->name);
			send_code(remote, code);
		}
		remote = remote->next;
	}
	return 0;
}

static int simsend_keysym(struct ir_remote* remote, const char* keysym)
{
	struct ir_ncode* code;

	code = get_code_by_name(remote, keysym);
	if (code != NULL) {
		send_code(remote, code);
		printf("%s\n", keysym);
	} else {
		fprintf(stderr, "No such key: %s\n", keysym);
		exit(EXIT_FAILURE);
	}
	return 0;
}

static int simsend_list(struct ir_remote* remote)
{
	char line[256];
	char keysym[32];
	struct ir_ncode* code;
	FILE* f;
	char* s;
	int r;

	f = fopen(opt_listfile, "r");
	s = fgets(line, sizeof(line), f);
	while (s != NULL) {
		r = sscanf(line, "%*x %*x %32s %*s", keysym);
		if (r != 1)
			r = sscanf(line, "%32s", keysym);
		if (r != 1) {
			printf("Cannot parse line: %s\n", line);
			continue;
		}
		code = get_code_by_name(remote, keysym);
		if (code == NULL) {
			printf("Illegal keycode: %s\n", keysym);
		} else {
			printf("%s\n", code->name);
			send_code(remote, code);
		}
		s = fgets(line, sizeof(line), f);
	}
	fclose(f);
	return 0;
}

int main(int argc, char* argv[])
{
	struct ir_remote* remote;
	char path[128];
	const loglevel_t level = options_get_app_loglevel("irsimsimsend");

	lirc_log_get_clientlog("irsimsend", path, sizeof(path));
	lirc_log_set_file(path);
	lirc_log_open("irsimsend", 1, level);

	options_load(argc, argv, NULL, parse_options);
        opt_startspace = options_getint("irsimsend:start-space");
        opt_count = options_getint("irsimsend:count");
        opt_keysym = options_getstring("irsimsend:keysym");
        opt_listfile = options_getstring("irsimsend:listfile");

	remote = setup(argv[optind]);
	if (opt_startspace != -1)
		send_space(opt_startspace);
	if (opt_keysym != NULL)
		simsend_keysym(remote, opt_keysym);
	else if (opt_listfile != NULL)
		simsend_list(remote);
	else
		simsend_remote(remote);
	return 0;
}
<commit_msg>irsimsend: Fix log setup typo.<commit_after>/****************************************************************************
** irsimsend.c *************************************************************
****************************************************************************
*
* irsimsend - send all codes defined in a given config file.
*
*/

#include <config.h>

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <getopt.h>

#include "lirc_private.h"
#include "lirc_client.h"

static const logchannel_t logchannel = LOG_APP;

static const char* const USAGE =
	"Send key symbols durations to fixed file 'simsend.out'.\n\n"
	"Synopsis:\n"
	"    irsimsend [-U path] [-s time] [-c count] <file>\n"
	"    irsimsend [-k keysym | -l listfile] [-U path] [-s time] [-c count]"
	" <file>\n"
	"    irsimsend [-h | -v]\n\n"
	"<file> is a lircd.conf type config file. In the first form, all keys in\n"
	"that file are sent.\n\n"
	"Options:\n"
	"    -U, --plugindir <path>:     Load drivers from <path>.\n"
	"    -c, --config <count>:       Repeat each key <count> times.\n"
	"    -l, --listfile <file>       Send symbols in file.\n"
	"    -k, --keysym <keysym>       Send a single keysym.\n"
	"    -s, --start-space <time>    Send a start space <time> us\n"
	"    -v, --version               Print version.\n"
	"    -h, --help                  Print this message.\n";

static struct option options[] = {
	{ "help",	 no_argument,	    NULL, 'h' },
	{ "version",	 no_argument,	    NULL, 'v' },
	{ "count",	 required_argument, NULL, 'c' },
	{ "keysym",	 required_argument, NULL, 'k' },
	{ "listfile",	 required_argument, NULL, 'l' },
	{ "pluginpath",	 required_argument, NULL, 'U' },
	{ "start-space", required_argument, NULL, 's' },
	{ 0,		 0,		    0,	  0   }
};

static const char* const OUTFILE = "simsend.out";

static int opt_count = 1;
static int opt_startspace = -1;
static const char* opt_keysym = NULL;
static const char* opt_listfile = NULL;

/** Set up default values for all command line options + filename. */
static void add_defaults(void)
{
	static char plugindir[128];
	const char* defaults[] = {
		"lircd:plugindir",	      plugindir,
		"irsimsend:driver",	      "devinput",
		"irsimsend:count",	      "1",
		"irsimsend:keysym",	      (const char*)NULL,
		"irsimsend:listfile",	      (const char*)NULL,
		"irsimsend:start-space"	      "-1",
		(const char*)NULL,	      (const char*)NULL
	};
	const char* s = getenv("LIRC_PLUGIN_PATH");

	strncpy(plugindir, s != NULL ? s : PLUGINDIR, sizeof(plugindir) - 1);
	options_add_defaults(defaults);
};

int parse_uint_arg(const char* optind, const char* errmsg)
{
	long c;

	c = strtol(optarg, NULL, 10);
	if (c > INT_MAX || c < 0 || errno == EINVAL || errno == ERANGE) {
		fputs(errmsg, stderr);
		exit(EXIT_FAILURE);
	}
	return (int)c;
}

static void parse_options(int argc, char** const argv)
{
	long c;

	add_defaults();

	while ((c = getopt_long(argc, argv, "c:hk:l:s:U:v", options, NULL))
	       != EOF) {
		switch (c) {
		case 'h':
			puts(USAGE);
			exit(EXIT_SUCCESS);
		case 'c':
			(void) parse_uint_arg(optarg, "Illegal count value\n");
			options_set_opt("irsimsend:count", optarg);
			break;
		case 'v':
			printf("%s\n", "irw " VERSION);
			exit(EXIT_SUCCESS);
		case 'U':
			options_set_opt("lircd:plugindir", optarg);
			break;
		case 'k':
			options_set_opt("irsimsend:keysym", optarg);
			break;
		case 'l':
			options_set_opt("irsimsend:listfile", optarg);
			break;
		case 's':
			(void) parse_uint_arg(optarg, "Illegal space value\n");
			options_set_opt("irsimsend:start-space", optarg);
			break;
		case '?':
			fprintf(stderr, "unrecognized option: -%c\n", optopt);
			fputs("Try `irsimsend -h' for more information.\n",
			      stderr);
			exit(EXIT_FAILURE);
		}
	}
	if (argc != optind + 1) {
		fputs(USAGE, stderr);
		exit(EXIT_FAILURE);
	}
}

static struct ir_remote* setup(const char* path)
{
	struct ir_remote* remote;
	FILE* f;

	if (hw_choose_driver("file") == -1) {
		fputs("Cannot load file driver (bad plugin path?)\n",
		      stderr);
		exit(EXIT_FAILURE);
	}
	unlink(OUTFILE);
	curr_driver->open_func(OUTFILE);
	curr_driver->init_func();

	if (opt_listfile != NULL && access(opt_listfile, R_OK) != 0) {
		fprintf(stderr, "Cannot open %s for read\n", opt_listfile);
		exit(EXIT_FAILURE);
	}
	f = fopen(path, "r");
	if (f == NULL) {
		fprintf(stderr, "Cannot open %s for read\n", path);
		exit(EXIT_FAILURE);
	}
	remote = read_config(f, path);
	fclose(f);
	if (remote == NULL) {
		fprintf(stderr, "Cannot parse %s\n", path);
		exit(EXIT_FAILURE);
	}
	remote->min_repeat = 0;
	return remote;
}

static void send_space(int duration)
{
	char buff[64];

	snprintf(buff, sizeof(buff), "send-space:%d", duration);
	drv_handle_options(buff);
}

static void send_code(struct ir_remote* remote, struct ir_ncode* code)
{
	int i;
	static char last_code[32] = { '\0' };

	code->transmit_state = NULL;
	if (has_toggle_mask(remote))
		remote->toggle_mask_state = 0;
	if (has_toggle_bit_mask(remote))
		remote->toggle_bit_mask_state =
			(remote->toggle_bit_mask_state ^ remote->toggle_bit_mask);
	code->transmit_state = NULL;
	remote->min_repeat = 0;
	if (strcmp(code->name, last_code) == 0)
		repeat_remote = remote;
	send_ir_ncode(remote, code, 0);
	repeat_remote = remote;
	for (i = 1; i < opt_count; i += 1)
		send_ir_ncode(remote, code, 0);
	repeat_remote = NULL;
	strncpy(last_code, code->name, sizeof(last_code));
}

static int simsend_remote(struct ir_remote* remote)
{
	struct ir_ncode* code;

	while (remote != NULL) {
		for (code = remote->codes; code->name != NULL; code++) {
			printf("%s\n", code->name);
			send_code(remote, code);
		}
		remote = remote->next;
	}
	return 0;
}

static int simsend_keysym(struct ir_remote* remote, const char* keysym)
{
	struct ir_ncode* code;

	code = get_code_by_name(remote, keysym);
	if (code != NULL) {
		send_code(remote, code);
		printf("%s\n", keysym);
	} else {
		fprintf(stderr, "No such key: %s\n", keysym);
		exit(EXIT_FAILURE);
	}
	return 0;
}

static int simsend_list(struct ir_remote* remote)
{
	char line[256];
	char keysym[32];
	struct ir_ncode* code;
	FILE* f;
	char* s;
	int r;

	f = fopen(opt_listfile, "r");
	s = fgets(line, sizeof(line), f);
	while (s != NULL) {
		r = sscanf(line, "%*x %*x %32s %*s", keysym);
		if (r != 1)
			r = sscanf(line, "%32s", keysym);
		if (r != 1) {
			printf("Cannot parse line: %s\n", line);
			continue;
		}
		code = get_code_by_name(remote, keysym);
		if (code == NULL) {
			printf("Illegal keycode: %s\n", keysym);
		} else {
			printf("%s\n", code->name);
			send_code(remote, code);
		}
		s = fgets(line, sizeof(line), f);
	}
	fclose(f);
	return 0;
}

int main(int argc, char* argv[])
{
	struct ir_remote* remote;
	char path[128];
	const loglevel_t level = options_get_app_loglevel("irsimsend");

	lirc_log_get_clientlog("irsimsend", path, sizeof(path));
	lirc_log_set_file(path);
	lirc_log_open("irsimsend", 1, level);

	options_load(argc, argv, NULL, parse_options);
        opt_startspace = options_getint("irsimsend:start-space");
        opt_count = options_getint("irsimsend:count");
        opt_keysym = options_getstring("irsimsend:keysym");
        opt_listfile = options_getstring("irsimsend:listfile");

	remote = setup(argv[optind]);
	if (opt_startspace != -1)
		send_space(opt_startspace);
	if (opt_keysym != NULL)
		simsend_keysym(remote, opt_keysym);
	else if (opt_listfile != NULL)
		simsend_list(remote);
	else
		simsend_remote(remote);
	return 0;
}
<|endoftext|>


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

#include <stdlib.h>
#include <string.h>
#include <zlib/zlib.h>

#include <nvbio/basic/console.h>
#include <nvbio/basic/packedstream.h>
#include <nvbio/io/sequence/bam.h>
#include <nvbio/io/sequence/sam.h>
#include <nvbio/io/sequence/sequence_encoder.h>

namespace nvbio {
namespace io {

///@addtogroup IO
///@{

///@addtogroup SequencesIO
///@{

///@addtogroup SequencesIODetail
///@{

SequenceDataFile_BAM::SequenceDataFile_BAM(
    const char*             read_file_name,
    const uint32            max_reads,
    const uint32            truncate_read_len,
    const SequenceEncoding  flags)
  : SequenceDataFile(max_reads, truncate_read_len, flags)
{
    fp = gzopen(read_file_name, "rb");
    if (fp == NULL)
    {
        // this will cause init() to fail below
        log_error(stderr, "unable to open BAM file %s\n", read_file_name);
        m_file_state = FILE_OPEN_FAILED;
    } else {
        m_file_state = FILE_OK;
    }
}

bool SequenceDataFile_BAM::readData(void *output, unsigned int len)
{
    unsigned int ret;

    ret = gzread(fp, output, len);
    if (ret > 0)
    {
        return true;
    } else {
        // check for EOF separately; zlib will not always return Z_STREAM_END at EOF below
        if (gzeof(fp))
        {
            m_file_state = FILE_EOF;
        } else {
            // ask zlib what happened and inform the user
            int err;
            const char *msg;

            msg = gzerror(fp, &err);
            // we're making the assumption that we never see Z_STREAM_END here
            assert(err != Z_STREAM_END);

            log_error(stderr, "error processing BAM file: zlib error %d (%s)\n", err, msg);
            m_file_state = FILE_STREAM_ERROR;
        }

        return false;
    }
}

// read in a structure field from fp
// returns error (local variable of the right type) if read fails
#define GZREAD(field)                                           \
    if (readData(&(field), sizeof(field)) == false) {           \
        return error;                                           \
    }

// skip bytes in fp
// note that gzseek won't actually detect EOF, so we don't check return values here
#define GZFWD(bytes) \
    gzseek(fp, (bytes), SEEK_CUR)

// skip a structure field in fp
#define GZSKIP(field) \
    gzseek(fp, sizeof(field), SEEK_CUR)

bool SequenceDataFile_BAM::init(void)
{
    // error constant for GZREAD
    static const bool error = false;

    BAM_header header;
    int c;

    if (fp == NULL)
    {
        // file failed to open
        return false;
    }

    // parse the BAM header
    GZREAD(header.magic);

    if (header.magic[0] != 'B' ||
        header.magic[1] != 'A' ||
        header.magic[2] != 'M' ||
        header.magic[3] != '\1')
    {
        log_error(stderr, "error parsing BAM file (invalid magic)\n");
        m_file_state = FILE_PARSE_ERROR;
        return false;
    }

    // read in header text length and skip header text
    GZREAD(header.l_text);
    GZFWD(header.l_text);

    // skip reference sequence data
    GZREAD(header.n_ref);
    for(c = 0; c < header.n_ref; c++)
    {
        BAM_reference ref;
        GZREAD(ref.l_name);
        GZFWD(ref.l_name + sizeof(ref.l_ref));
    }

    return true;
}

namespace {

// decode a BAM bp into ascii
inline unsigned char decode_BAM_bp(uint8 bp)
{
    static const char table[] = "=ACMGRSVTWYHKDBN";

    assert(bp < 16);
    return table[bp];
}

}

// grab the next chunk of reads from the file, up to max_reads
int SequenceDataFile_BAM::nextChunk(SequenceEncoder *output, uint32 max_reads, uint32 max_bps)
{
    if (max_bps < SequenceDataFile::LONG_READ)
        return 0;

    // error code for gzread
    static const int error = -1;

    // small utility structure to keep track of data buffers and free them as appropriate
    // (note the slightly evil initializer that sets all pointers to NULL)
    struct data
    {
        char *read_name;
        uint8 *encoded_read;
        uint8 *decoded_read;
        uint8 *quality;

        ~data()
        {
            if (read_name)
                free(read_name);

            if (encoded_read)
                free(encoded_read);

            if (decoded_read)
                free(decoded_read);

            if (quality)
                free(quality);
        }
    } data = { };

    // utility structure to keep track of alignment header data
    BAM_alignment align;

    z_off_t read_block_start;
    int read_name_len;
    int read_flags;
    int cigar_len;
    int encoded_read_len;

    int c;

    // are we done?
    if (gzeof(fp))
    {
        m_file_state = FILE_EOF;
        return 0;
    }

    // parse and skip all non-primary reads
    do {
        // read in the block_size
        GZREAD(align.block_size);

        // record the starting file position for this read block
        read_block_start = gztell(fp);

        // skip uninsteresting fields
        GZFWD(sizeof(align.refID) +
              sizeof(align.pos));

        GZREAD(align.bin_mq_nl);
        GZREAD(align.flag_nc);

        // compute read flags
        read_flags = align.flag_nc >> 16;
        if (read_flags & SAMFlag_SecondaryAlignment)
        {
            // we're not interested in this read; skip the remainder of the read block and loop
            uint32 skip = align.block_size - (gztell(fp) - read_block_start);
            assert(skip);
            GZFWD(skip);

            continue;
        }
    } while (read_flags & SAMFlag_SecondaryAlignment);

    // this is a primary read, so read the read
    GZREAD(align.l_seq);
    GZFWD(sizeof(align.next_refID) +
          sizeof(align.next_pos) +
          sizeof(align.tlen));

    // read in the name (and add a null-terminator just in case)
    read_name_len = align.bin_mq_nl & 0xff;
    data.read_name = (char *) malloc(read_name_len + 1);
    data.read_name[read_name_len] = 0;

    if (gzread(fp, data.read_name, read_name_len) != read_name_len)
    {
        log_error(stderr, "error processing BAM file (could not fetch read name)\n");
        m_file_state = FILE_STREAM_ERROR;
        return 0;
    }

    // skip the cigar
    cigar_len = (align.flag_nc & 0xffff) * sizeof(uint32);
    GZFWD(cigar_len);

    // grab the read data
    encoded_read_len = (align.l_seq + 1) / 2;
    data.encoded_read = (uint8 *) malloc((align.l_seq + 1) / 2);

    if (gzread(fp, data.encoded_read, encoded_read_len) != encoded_read_len)
    {
        log_error(stderr, "error processing BAM file (could not fetch sequence data)\n");
        m_file_state = FILE_STREAM_ERROR;
        return 0;
    }

    // read in the quality data
    data.quality = (uint8 *) malloc(align.l_seq);
    if (gzread(fp, data.quality, align.l_seq) != align.l_seq)
    {
        log_error(stderr, "error processing BAM file (could not fetch quality data)\n");
        m_file_state = FILE_STREAM_ERROR;
        return 0;
    }

    // skip the rest of the read block
    uint32 skip = align.block_size - (gztell(fp) - read_block_start);
    GZFWD(skip);

    // decode the read data into a null-terminated string
    data.decoded_read = (uint8 *) malloc(align.l_seq + 1);
    data.decoded_read[align.l_seq] = 0;

    PackedStream<uint8*, uint8, 4, true> stream(data.encoded_read);
    for(c = 0; c < align.l_seq; c++)
    {
        data.decoded_read[c] = decode_BAM_bp(stream[c]);
    }

    if (m_flags & FORWARD)
    {
        const SequenceEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceEncoder::REVERSE_COMPLEMENT_OP : SequenceEncoder::NO_OP;

        // add the read into the batch
        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }
    if (m_flags & REVERSE)
    {
        const SequenceEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceEncoder::COMPLEMENT_OP : SequenceEncoder::REVERSE_OP;

        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }
    if (m_flags & FORWARD_COMPLEMENT)
    {
        const SequenceEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceEncoder::REVERSE_OP : SequenceEncoder::COMPLEMENT_OP;

        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }
    if (m_flags & REVERSE_COMPLEMENT)
    {
        const SequenceEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceEncoder::NO_OP : SequenceEncoder::REVERSE_COMPLEMENT_OP;

        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }

    // we always return 1 read at a time
    return 1;
}

///@} // SequencesIODetail
///@} // SequencesIO
///@} // IO

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

#include <stdlib.h>
#include <string.h>
#include <zlib/zlib.h>

#include <nvbio/basic/console.h>
#include <nvbio/basic/packedstream.h>
#include <nvbio/io/sequence/bam.h>
#include <nvbio/io/sequence/sam.h>
#include <nvbio/io/sequence/sequence_encoder.h>

namespace nvbio {
namespace io {

///@addtogroup IO
///@{

///@addtogroup SequencesIO
///@{

///@addtogroup SequencesIODetail
///@{

SequenceDataFile_BAM::SequenceDataFile_BAM(
    const char*             read_file_name,
    const uint32            max_reads,
    const uint32            truncate_read_len,
    const SequenceEncoding  flags)
  : SequenceDataFile(max_reads, truncate_read_len, flags)
{
    fp = gzopen(read_file_name, "rb");
    if (fp == NULL)
    {
        // this will cause init() to fail below
        log_error(stderr, "unable to open BAM file %s\n", read_file_name);
        m_file_state = FILE_OPEN_FAILED;
    } else {
        m_file_state = FILE_OK;
    }
}

bool SequenceDataFile_BAM::readData(void *output, unsigned int len)
{
    unsigned int ret;

    ret = gzread(fp, output, len);
    if (ret > 0)
    {
        return true;
    } else {
        // check for EOF separately; zlib will not always return Z_STREAM_END at EOF below
        if (gzeof(fp))
        {
            m_file_state = FILE_EOF;
        } else {
            // ask zlib what happened and inform the user
            int err;
            const char *msg;

            msg = gzerror(fp, &err);
            // we're making the assumption that we never see Z_STREAM_END here
            assert(err != Z_STREAM_END);

            log_error(stderr, "error processing BAM file: zlib error %d (%s)\n", err, msg);
            m_file_state = FILE_STREAM_ERROR;
        }

        return false;
    }
}

// read in a structure field from fp
// returns error (local variable of the right type) if read fails
#define GZREAD(field)                                           \
    if (readData(&(field), sizeof(field)) == false) {           \
        return error;                                           \
    }

// skip bytes in fp
// note that gzseek won't actually detect EOF, so we don't check return values here
#define GZFWD(bytes) \
    gzseek(fp, (bytes), SEEK_CUR)

// skip a structure field in fp
#define GZSKIP(field) \
    gzseek(fp, sizeof(field), SEEK_CUR)

bool SequenceDataFile_BAM::init(void)
{
    // error constant for GZREAD
    static const bool error = false;

    BAM_header header;
    int c;

    if (fp == NULL)
    {
        // file failed to open
        return false;
    }

    // parse the BAM header
    GZREAD(header.magic);

    if (header.magic[0] != 'B' ||
        header.magic[1] != 'A' ||
        header.magic[2] != 'M' ||
        header.magic[3] != '\1')
    {
        log_error(stderr, "error parsing BAM file (invalid magic)\n");
        m_file_state = FILE_PARSE_ERROR;
        return false;
    }

    // read in header text length and skip header text
    GZREAD(header.l_text);
    GZFWD(header.l_text);

    // skip reference sequence data
    GZREAD(header.n_ref);
    for(c = 0; c < header.n_ref; c++)
    {
        BAM_reference ref;
        GZREAD(ref.l_name);
        GZFWD(ref.l_name + sizeof(ref.l_ref));
    }

    return true;
}

namespace {

// decode a BAM bp into ascii
inline unsigned char decode_BAM_bp(uint8 bp)
{
    static const char table[] = "=ACMGRSVTWYHKDBN";

    assert(bp < 16);
    return table[bp];
}

}

// grab the next chunk of reads from the file, up to max_reads
int SequenceDataFile_BAM::nextChunk(SequenceDataEncoder *output, uint32 max_reads, uint32 max_bps)
{
    if (max_bps < SequenceDataFile::LONG_READ)
        return 0;

    // error code for gzread
    static const int error = -1;

    // small utility structure to keep track of data buffers and free them as appropriate
    // (note the slightly evil initializer that sets all pointers to NULL)
    struct data
    {
        char *read_name;
        uint8 *encoded_read;
        uint8 *decoded_read;
        uint8 *quality;

        ~data()
        {
            if (read_name)
                free(read_name);

            if (encoded_read)
                free(encoded_read);

            if (decoded_read)
                free(decoded_read);

            if (quality)
                free(quality);
        }
    } data = { };

    // utility structure to keep track of alignment header data
    BAM_alignment align;

    z_off_t read_block_start;
    int read_name_len;
    int read_flags;
    int cigar_len;
    int encoded_read_len;

    int c;

    // are we done?
    if (gzeof(fp))
    {
        m_file_state = FILE_EOF;
        return 0;
    }

    // parse and skip all non-primary reads
    do {
        // read in the block_size
        GZREAD(align.block_size);

        // record the starting file position for this read block
        read_block_start = gztell(fp);

        // skip uninsteresting fields
        GZFWD(sizeof(align.refID) +
              sizeof(align.pos));

        GZREAD(align.bin_mq_nl);
        GZREAD(align.flag_nc);

        // compute read flags
        read_flags = align.flag_nc >> 16;
        if (read_flags & SAMFlag_SecondaryAlignment)
        {
            // we're not interested in this read; skip the remainder of the read block and loop
            uint32 skip = align.block_size - (gztell(fp) - read_block_start);
            assert(skip);
            GZFWD(skip);

            continue;
        }
    } while (read_flags & SAMFlag_SecondaryAlignment);

    // this is a primary read, so read the read
    GZREAD(align.l_seq);
    GZFWD(sizeof(align.next_refID) +
          sizeof(align.next_pos) +
          sizeof(align.tlen));

    // read in the name (and add a null-terminator just in case)
    read_name_len = align.bin_mq_nl & 0xff;
    data.read_name = (char *) malloc(read_name_len + 1);
    data.read_name[read_name_len] = 0;

    if (gzread(fp, data.read_name, read_name_len) != read_name_len)
    {
        log_error(stderr, "error processing BAM file (could not fetch read name)\n");
        m_file_state = FILE_STREAM_ERROR;
        return 0;
    }

    // skip the cigar
    cigar_len = (align.flag_nc & 0xffff) * sizeof(uint32);
    GZFWD(cigar_len);

    // grab the read data
    encoded_read_len = (align.l_seq + 1) / 2;
    data.encoded_read = (uint8 *) malloc((align.l_seq + 1) / 2);

    if (gzread(fp, data.encoded_read, encoded_read_len) != encoded_read_len)
    {
        log_error(stderr, "error processing BAM file (could not fetch sequence data)\n");
        m_file_state = FILE_STREAM_ERROR;
        return 0;
    }

    // read in the quality data
    data.quality = (uint8 *) malloc(align.l_seq);
    if (gzread(fp, data.quality, align.l_seq) != align.l_seq)
    {
        log_error(stderr, "error processing BAM file (could not fetch quality data)\n");
        m_file_state = FILE_STREAM_ERROR;
        return 0;
    }

    // skip the rest of the read block
    uint32 skip = align.block_size - (gztell(fp) - read_block_start);
    GZFWD(skip);

    // decode the read data into a null-terminated string
    data.decoded_read = (uint8 *) malloc(align.l_seq + 1);
    data.decoded_read[align.l_seq] = 0;

    PackedStream<uint8*, uint8, 4, true> stream(data.encoded_read);
    for(c = 0; c < align.l_seq; c++)
    {
        data.decoded_read[c] = decode_BAM_bp(stream[c]);
    }

    if (m_flags & FORWARD)
    {
        const SequenceDataEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceDataEncoder::REVERSE_COMPLEMENT_OP : SequenceDataEncoder::NO_OP;

        // add the read into the batch
        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }
    if (m_flags & REVERSE)
    {
        const SequenceDataEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceDataEncoder::COMPLEMENT_OP : SequenceDataEncoder::REVERSE_OP;

        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }
    if (m_flags & FORWARD_COMPLEMENT)
    {
        const SequenceDataEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceDataEncoder::REVERSE_OP : SequenceDataEncoder::COMPLEMENT_OP;

        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }
    if (m_flags & REVERSE_COMPLEMENT)
    {
        const SequenceDataEncoder::StrandOp op = (read_flags & SAMFlag_ReverseComplemented) ?
            SequenceDataEncoder::NO_OP : SequenceDataEncoder::REVERSE_COMPLEMENT_OP;

        output->push_back(align.l_seq,
                          data.read_name,
                          data.decoded_read,
                          data.quality,
                          Phred,
                          m_truncate_read_len,
                          op );
    }

    // we always return 1 read at a time
    return 1;
}

///@} // SequencesIODetail
///@} // SequencesIO
///@} // IO

} // namespace io
} // namespace nvbio
<|endoftext|>


<commit_before>#include "fof.hpp"
#include <list>
#include <set>
#include <iostream>
#include <cmath>

struct Point {
    size_t index;
    double *loc;

    Point(size_t index, double *loc):index(index), loc(loc)
    {}
};

inline double dist(double *p1, double *p2, size_t ndim)
{
    double d2 = 0.;
    for(size_t i = 0 ; i < ndim ; ++i) {
        d2 += pow(p1[i] - p2[i], 2);
    }
    return sqrt(d2);
}

std::list< std::list<size_t> > friends_of_friends(double *data, size_t npts, size_t ndim, double linking_length)
{
    std::list<Point> unused;
    std::list< std::list< size_t > > groups;
    for(size_t i=0 ; i<npts ; ++i) {
        unused.push_back(Point(i, data + i*ndim));
    }

    while( unused.size() > 0 ) {
        std::list<Point> toadd;
        toadd.push_back(unused.front());
        unused.pop_front();

        auto toadd_it = toadd.begin();
        for(auto toadd_it = toadd.begin() ; toadd_it != toadd.end() ; ++ toadd_it) {
            auto unused_it = unused.begin();
            while(unused_it != unused.end()) {
                if(dist(unused_it->loc, toadd_it->loc, ndim) < linking_length) {
                    toadd.push_back(*unused_it);
                    unused.erase(unused_it++);
                } else {
                    ++unused_it;
                }
            }
        }

        std::list<size_t> group;
        for(auto& p : toadd) {
            group.push_back(p.index);
        }
        groups.push_back(group);
    }

    return groups;
}<commit_msg>Remove unused import<commit_after>#include "fof.hpp"
#include <list>
#include <iostream>
#include <cmath>

struct Point {
    size_t index;
    double *loc;

    Point(size_t index, double *loc):index(index), loc(loc)
    {}
};

inline double dist(double *p1, double *p2, size_t ndim)
{
    double d2 = 0.;
    for(size_t i = 0 ; i < ndim ; ++i) {
        d2 += pow(p1[i] - p2[i], 2);
    }
    return sqrt(d2);
}

std::list< std::list<size_t> > friends_of_friends(double *data, size_t npts, size_t ndim, double linking_length)
{
    std::list<Point> unused;
    std::list< std::list< size_t > > groups;
    for(size_t i=0 ; i<npts ; ++i) {
        unused.push_back(Point(i, data + i*ndim));
    }

    while( unused.size() > 0 ) {
        std::list<Point> toadd;
        toadd.push_back(unused.front());
        unused.pop_front();

        auto toadd_it = toadd.begin();
        for(auto toadd_it = toadd.begin() ; toadd_it != toadd.end() ; ++ toadd_it) {
            auto unused_it = unused.begin();
            while(unused_it != unused.end()) {
                if(dist(unused_it->loc, toadd_it->loc, ndim) < linking_length) {
                    toadd.push_back(*unused_it);
                    unused.erase(unused_it++);
                } else {
                    ++unused_it;
                }
            }
        }

        std::list<size_t> group;
        for(auto& p : toadd) {
            group.push_back(p.index);
        }
        groups.push_back(group);
    }

    return groups;
}<|endoftext|>


<commit_before>#include "hooks_py.h"
#include "simulator.h"
#include "config.hpp"

static PyObject *
getConfigString(PyObject *self, PyObject *args)
{
   const char *key = NULL;
   SInt64 index = -1;
   String result = "";

   if (!PyArg_ParseTuple(args, "s|i", &key, &index))
      return NULL;

   if (index != -1)
      result = Sim()->getCfg()->getStringArray(key, index);
   else
      result = Sim()->getCfg()->getString(key);

   return PyString_FromString(result.c_str());
}

static PyMethodDef PyConfigMethods[] = {
   {"get",  getConfigString, METH_VARARGS, "Get configuration variable."},
   {NULL, NULL, 0, NULL} /* Sentinel */
};

void HooksPy::PyConfig::setup(void)
{
   PyObject *pModule = Py_InitModule("sim_config", PyConfigMethods);

   PyObject *pOutputdir = PyString_FromString(Sim()->getConfig()->formatOutputFileName("").c_str());
   PyObject_SetAttrString(pModule, "output_dir", pOutputdir);
   Py_DECREF(pOutputdir);

   PyObject *pNcores = PyInt_FromLong(Sim()->getConfig()->getApplicationCores());
   PyObject_SetAttrString(pModule, "ncores", pNcores);
   Py_DECREF(pNcores);
}
<commit_msg>[scripting] Add additional config accessor methods to allow for explicit conversion. This is needed for boolean values, as the string 'false' needs to be a Python False<commit_after>#include "hooks_py.h"
#include "simulator.h"
#include "config.hpp"

static PyObject *
getConfigString(PyObject *self, PyObject *args)
{
   const char *key = NULL;
   SInt64 index = -1;
   String result = "";

   if (!PyArg_ParseTuple(args, "s|i", &key, &index))
      return NULL;

   if (index != -1)
      result = Sim()->getCfg()->getStringArray(key, index);
   else
      result = Sim()->getCfg()->getString(key);

   return PyString_FromString(result.c_str());
}

static PyObject *
getConfigInt(PyObject *self, PyObject *args)
{
   const char *key = NULL;
   SInt64 index = -1;
   SInt64 result = 0;

   if (!PyArg_ParseTuple(args, "s|i", &key, &index))
      return NULL;

   if (index != -1)
      result = Sim()->getCfg()->getIntArray(key, index);
   else
      result = Sim()->getCfg()->getInt(key);

   return PyLong_FromLongLong(result);
}

static PyObject *
getConfigFloat(PyObject *self, PyObject *args)
{
   const char *key = NULL;
   SInt64 index = -1;
   double result = 0;

   if (!PyArg_ParseTuple(args, "s|i", &key, &index))
      return NULL;

   if (index != -1)
      result = Sim()->getCfg()->getFloatArray(key, index);
   else
      result = Sim()->getCfg()->getFloat(key);

   return PyFloat_FromDouble(result);
}

static PyObject *
getConfigBool(PyObject *self, PyObject *args)
{
   const char *key = NULL;
   SInt64 index = -1;
   bool result = false;

   if (!PyArg_ParseTuple(args, "s|i", &key, &index))
      return NULL;

   if (index != -1)
      result = Sim()->getCfg()->getBoolArray(key, index);
   else
      result = Sim()->getCfg()->getBool(key);

   return PyBool_FromLong(result);
}

static PyMethodDef PyConfigMethods[] = {
   {"get",  getConfigString, METH_VARARGS, "Get configuration variable."},
   {"get_int",  getConfigInt, METH_VARARGS, "Get configuration variable."},
   {"get_float",  getConfigFloat, METH_VARARGS, "Get configuration variable."},
   {"get_bool",  getConfigBool, METH_VARARGS, "Get configuration variable."},
   {NULL, NULL, 0, NULL} /* Sentinel */
};

void HooksPy::PyConfig::setup(void)
{
   PyObject *pModule = Py_InitModule("sim_config", PyConfigMethods);

   PyObject *pOutputdir = PyString_FromString(Sim()->getConfig()->formatOutputFileName("").c_str());
   PyObject_SetAttrString(pModule, "output_dir", pOutputdir);
   Py_DECREF(pOutputdir);

   PyObject *pNcores = PyInt_FromLong(Sim()->getConfig()->getApplicationCores());
   PyObject_SetAttrString(pModule, "ncores", pNcores);
   Py_DECREF(pNcores);
}
<|endoftext|>


<commit_before>#pragma once

#include "search/categories_cache.hpp"
#include "search/cbv.hpp"
#include "search/mwm_context.hpp"

#include "indexer/ftypes_matcher.hpp"
#include "indexer/mwm_set.hpp"

#include "std/map.hpp"
#include "std/shared_ptr.hpp"
#include "std/sstream.hpp"
#include "std/string.hpp"
#include "std/unique_ptr.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"

class FeatureType;

namespace search
{
namespace hotels_filter
{
struct Rating
{
  using Value = float;

  static Value const kDefault;

  static bool Lt(Value lhs, Value rhs) { return lhs + 0.05 < rhs; }
  static bool Gt(Value lhs, Value rhs) { return lhs > rhs + 0.05; }
  static bool Eq(Value lhs, Value rhs) { return !Lt(lhs, rhs) && !Gt(lhs, rhs); }

  template <typename Description>
  static Value Select(Description const & d)
  {
    return d.m_rating;
  }

  static char const * Name() { return "Rating"; }
};

struct PriceRate
{
  using Value = int;

  static Value const kDefault;

  static bool Lt(Value lhs, Value rhs) { return lhs < rhs; }
  static bool Gt(Value lhs, Value rhs) { return lhs > rhs; }
  static bool Eq(Value lhs, Value rhs) { return lhs == rhs; }

  template <typename Description>
  static Value Select(Description const & d)
  {
    return d.m_priceRate;
  }

  static char const * Name() { return "PriceRate"; }
};

struct Description
{
  void FromFeature(FeatureType & ft);

  Rating::Value m_rating = Rating::kDefault;
  PriceRate::Value m_priceRate = PriceRate::kDefault;
  unsigned m_types = 0;
};

struct Rule
{
  virtual ~Rule() = default;

  static bool IsIdentical(shared_ptr<Rule> const & lhs, shared_ptr<Rule> const & rhs);

  virtual bool Matches(Description const & d) const = 0;
  virtual bool IdenticalTo(Rule const & rhs) const = 0;
  virtual string ToString() const = 0;
};

string DebugPrint(Rule const & rule);

template <typename Field>
struct EqRule final : public Rule
{
  using Value = typename Field::Value;

  explicit EqRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    return Field::Eq(Field::Select(d), m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<EqRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " == " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct LtRule final : public Rule
{
  using Value = typename Field::Value;

  explicit LtRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    return Field::Lt(Field::Select(d), m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<LtRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " < " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct LeRule final : public Rule
{
  using Value = typename Field::Value;

  explicit LeRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    auto const value = Field::Select(d);
    return Field::Lt(value, m_value) || Field::Eq(value, m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<LeRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " <= " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct GtRule final : public Rule
{
  using Value = typename Field::Value;

  explicit GtRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    return Field::Gt(Field::Select(d), m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<GtRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " > " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct GeRule final : public Rule
{
  using Value = typename Field::Value;

  explicit GeRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    auto const value = Field::Select(d);
    return Field::Gt(value, m_value) || Field::Eq(value, m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<GeRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " >= " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

struct AndRule final : public Rule
{
  AndRule(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs) : m_lhs(move(lhs)), m_rhs(move(rhs)) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    bool matches = true;
    if (m_lhs)
      matches = matches && m_lhs->Matches(d);
    if (m_rhs)
      matches = matches && m_rhs->Matches(d);
    return matches;
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<AndRule const *>(&rhs);
    return r && IsIdentical(m_lhs, r->m_lhs) && IsIdentical(m_rhs, r->m_rhs);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[";
    os << (m_lhs ? m_lhs->ToString() : "<none>");
    os << " && ";
    os << (m_rhs ? m_rhs->ToString() : "<none>");
    os << "]";
    return os.str();
  }

  shared_ptr<Rule> m_lhs;
  shared_ptr<Rule> m_rhs;
};

struct OrRule final : public Rule
{
  OrRule(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs) : m_lhs(move(lhs)), m_rhs(move(rhs)) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    bool matches = false;
    if (m_lhs)
      matches = matches || m_lhs->Matches(d);
    if (m_rhs)
      matches = matches || m_rhs->Matches(d);
    return matches;
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<OrRule const *>(&rhs);
    return r && IsIdentical(m_lhs, r->m_lhs) && IsIdentical(m_rhs, r->m_rhs);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[";
    os << (m_lhs ? m_lhs->ToString() : "<none>");
    os << " || ";
    os << (m_rhs ? m_rhs->ToString() : "<none>");
    os << "]";
    return os.str();
  }

  shared_ptr<Rule> m_lhs;
  shared_ptr<Rule> m_rhs;
};

struct OneOfRule final : public Rule
{
  explicit OneOfRule(unsigned types) : m_types(types) {}

  // Rule overrides:
  bool Matches(Description const & d) const override { return (d.m_types & m_types) != 0; }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<OneOfRule const *>(&rhs);
    return r && m_types == r->m_types;
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ one of:";
    for (size_t i = 0; i < static_cast<size_t>(ftypes::IsHotelChecker::Type::Count); ++i)
    {
      auto const type = static_cast<ftypes::IsHotelChecker::Type>(i);
      os << " " << ftypes::IsHotelChecker::GetHotelTypeTag(type);
    }
    os << " ]";
    return os.str();
  }

  unsigned m_types;
};

template <typename Field>
shared_ptr<Rule> Eq(typename Field::Value value)
{
  return make_shared<EqRule<Field>>(value);
}

template <typename Field>
shared_ptr<Rule> Lt(typename Field::Value value)
{
  return make_shared<LtRule<Field>>(value);
}

template <typename Field>
shared_ptr<Rule> Le(typename Field::Value value)
{
  return make_shared<LeRule<Field>>(value);
}

template <typename Field>
inline shared_ptr<Rule> Gt(typename Field::Value value)
{
  return make_shared<GtRule<Field>>(value);
}

template <typename Field>
shared_ptr<Rule> Ge(typename Field::Value value)
{
  return make_shared<GeRule<Field>>(value);
}

inline shared_ptr<Rule> And(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs)
{
  return make_shared<AndRule>(lhs, rhs);
}

inline shared_ptr<Rule> Or(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs)
{
  return make_shared<OrRule>(lhs, rhs);
}

inline shared_ptr<Rule> Is(ftypes::IsHotelChecker::Type type)
{
  CHECK(type != ftypes::IsHotelChecker::Type::Count, ());
  return make_shared<OneOfRule>(1U << static_cast<unsigned>(type));
}

inline shared_ptr<Rule> OneOf(unsigned types) { return make_shared<OneOfRule>(types); }

class HotelsFilter
{
public:
  using Descriptions = vector<pair<uint32_t, Description>>;

  class ScopedFilter
  {
  public:
    ScopedFilter(MwmSet::MwmId const & mwmId, Descriptions const & descriptions,
                 shared_ptr<Rule> rule);

    bool Matches(FeatureID const & fid) const;

  private:
    MwmSet::MwmId const m_mwmId;
    Descriptions const & m_descriptions;
    shared_ptr<Rule> const m_rule;
  };

  HotelsFilter(HotelsCache & hotels);

  unique_ptr<ScopedFilter> MakeScopedFilter(MwmContext const & context, shared_ptr<Rule> rule);

  void ClearCaches();

private:
  Descriptions const & GetDescriptions(MwmContext const & context);

  HotelsCache & m_hotels;
  map<MwmSet::MwmId, Descriptions> m_descriptions;
};
}  // namespace hotels_filter
}  // namespace search
<commit_msg>Review fixes.<commit_after>#pragma once

#include "search/categories_cache.hpp"
#include "search/cbv.hpp"
#include "search/mwm_context.hpp"

#include "indexer/ftypes_matcher.hpp"
#include "indexer/mwm_set.hpp"

#include "std/map.hpp"
#include "std/shared_ptr.hpp"
#include "std/sstream.hpp"
#include "std/string.hpp"
#include "std/unique_ptr.hpp"
#include "std/utility.hpp"
#include "std/vector.hpp"

class FeatureType;

namespace search
{
namespace hotels_filter
{
struct Rating
{
  using Value = float;

  static Value const kDefault;

  static bool Lt(Value lhs, Value rhs) { return lhs + 0.05 < rhs; }
  static bool Gt(Value lhs, Value rhs) { return lhs > rhs + 0.05; }
  static bool Eq(Value lhs, Value rhs) { return !Lt(lhs, rhs) && !Gt(lhs, rhs); }

  template <typename Description>
  static Value Select(Description const & d)
  {
    return d.m_rating;
  }

  static char const * Name() { return "Rating"; }
};

struct PriceRate
{
  using Value = int;

  static Value const kDefault;

  static bool Lt(Value lhs, Value rhs) { return lhs < rhs; }
  static bool Gt(Value lhs, Value rhs) { return lhs > rhs; }
  static bool Eq(Value lhs, Value rhs) { return lhs == rhs; }

  template <typename Description>
  static Value Select(Description const & d)
  {
    return d.m_priceRate;
  }

  static char const * Name() { return "PriceRate"; }
};

struct Description
{
  void FromFeature(FeatureType & ft);

  Rating::Value m_rating = Rating::kDefault;
  PriceRate::Value m_priceRate = PriceRate::kDefault;
  unsigned m_types = 0;
};

struct Rule
{
  virtual ~Rule() = default;

  static bool IsIdentical(shared_ptr<Rule> const & lhs, shared_ptr<Rule> const & rhs);

  virtual bool Matches(Description const & d) const = 0;
  virtual bool IdenticalTo(Rule const & rhs) const = 0;
  virtual string ToString() const = 0;
};

string DebugPrint(Rule const & rule);

template <typename Field>
struct EqRule final : public Rule
{
  using Value = typename Field::Value;

  explicit EqRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    return Field::Eq(Field::Select(d), m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<EqRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " == " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct LtRule final : public Rule
{
  using Value = typename Field::Value;

  explicit LtRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    return Field::Lt(Field::Select(d), m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<LtRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " < " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct LeRule final : public Rule
{
  using Value = typename Field::Value;

  explicit LeRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    auto const value = Field::Select(d);
    return Field::Lt(value, m_value) || Field::Eq(value, m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<LeRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " <= " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct GtRule final : public Rule
{
  using Value = typename Field::Value;

  explicit GtRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    return Field::Gt(Field::Select(d), m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<GtRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " > " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

template <typename Field>
struct GeRule final : public Rule
{
  using Value = typename Field::Value;

  explicit GeRule(Value value) : m_value(value) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    auto const value = Field::Select(d);
    return Field::Gt(value, m_value) || Field::Eq(value, m_value);
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<GeRule const *>(&rhs);
    return r && Field::Eq(r->m_value, m_value);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ " << Field::Name() << " >= " << m_value << " ]";
    return os.str();
  }

  Value const m_value;
};

struct AndRule final : public Rule
{
  AndRule(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs) : m_lhs(move(lhs)), m_rhs(move(rhs)) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    bool matches = true;
    if (m_lhs)
      matches = matches && m_lhs->Matches(d);
    if (m_rhs)
      matches = matches && m_rhs->Matches(d);
    return matches;
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<AndRule const *>(&rhs);
    return r && IsIdentical(m_lhs, r->m_lhs) && IsIdentical(m_rhs, r->m_rhs);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[";
    os << (m_lhs ? m_lhs->ToString() : "<none>");
    os << " && ";
    os << (m_rhs ? m_rhs->ToString() : "<none>");
    os << "]";
    return os.str();
  }

  shared_ptr<Rule> m_lhs;
  shared_ptr<Rule> m_rhs;
};

struct OrRule final : public Rule
{
  OrRule(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs) : m_lhs(move(lhs)), m_rhs(move(rhs)) {}

  // Rule overrides:
  bool Matches(Description const & d) const override
  {
    bool matches = false;
    if (m_lhs)
      matches = matches || m_lhs->Matches(d);
    if (m_rhs)
      matches = matches || m_rhs->Matches(d);
    return matches;
  }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<OrRule const *>(&rhs);
    return r && IsIdentical(m_lhs, r->m_lhs) && IsIdentical(m_rhs, r->m_rhs);
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[";
    os << (m_lhs ? m_lhs->ToString() : "<none>");
    os << " || ";
    os << (m_rhs ? m_rhs->ToString() : "<none>");
    os << "]";
    return os.str();
  }

  shared_ptr<Rule> m_lhs;
  shared_ptr<Rule> m_rhs;
};

struct OneOfRule final : public Rule
{
  explicit OneOfRule(unsigned types) : m_types(types) {}

  // Rule overrides:
  bool Matches(Description const & d) const override { return (d.m_types & m_types) != 0; }

  bool IdenticalTo(Rule const & rhs) const override
  {
    auto const * r = dynamic_cast<OneOfRule const *>(&rhs);
    return r && m_types == r->m_types;
  }

  string ToString() const override
  {
    ostringstream os;
    os << "[ one of:";
    for (size_t i = 0; i < static_cast<size_t>(ftypes::IsHotelChecker::Type::Count); ++i)
    {
      unsigned const bit = 1U << i;
      if ((m_types & bit) == 0)
        continue;

      auto const type = static_cast<ftypes::IsHotelChecker::Type>(i);
      os << " " << ftypes::IsHotelChecker::GetHotelTypeTag(type);
    }
    os << " ]";
    return os.str();
  }

  unsigned m_types;
};

template <typename Field>
shared_ptr<Rule> Eq(typename Field::Value value)
{
  return make_shared<EqRule<Field>>(value);
}

template <typename Field>
shared_ptr<Rule> Lt(typename Field::Value value)
{
  return make_shared<LtRule<Field>>(value);
}

template <typename Field>
shared_ptr<Rule> Le(typename Field::Value value)
{
  return make_shared<LeRule<Field>>(value);
}

template <typename Field>
inline shared_ptr<Rule> Gt(typename Field::Value value)
{
  return make_shared<GtRule<Field>>(value);
}

template <typename Field>
shared_ptr<Rule> Ge(typename Field::Value value)
{
  return make_shared<GeRule<Field>>(value);
}

inline shared_ptr<Rule> And(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs)
{
  return make_shared<AndRule>(lhs, rhs);
}

inline shared_ptr<Rule> Or(shared_ptr<Rule> lhs, shared_ptr<Rule> rhs)
{
  return make_shared<OrRule>(lhs, rhs);
}

inline shared_ptr<Rule> Is(ftypes::IsHotelChecker::Type type)
{
  CHECK(type != ftypes::IsHotelChecker::Type::Count, ());
  return make_shared<OneOfRule>(1U << static_cast<unsigned>(type));
}

inline shared_ptr<Rule> OneOf(unsigned types) { return make_shared<OneOfRule>(types); }

class HotelsFilter
{
public:
  using Descriptions = vector<pair<uint32_t, Description>>;

  class ScopedFilter
  {
  public:
    ScopedFilter(MwmSet::MwmId const & mwmId, Descriptions const & descriptions,
                 shared_ptr<Rule> rule);

    bool Matches(FeatureID const & fid) const;

  private:
    MwmSet::MwmId const m_mwmId;
    Descriptions const & m_descriptions;
    shared_ptr<Rule> const m_rule;
  };

  HotelsFilter(HotelsCache & hotels);

  unique_ptr<ScopedFilter> MakeScopedFilter(MwmContext const & context, shared_ptr<Rule> rule);

  void ClearCaches();

private:
  Descriptions const & GetDescriptions(MwmContext const & context);

  HotelsCache & m_hotels;
  map<MwmSet::MwmId, Descriptions> m_descriptions;
};
}  // namespace hotels_filter
}  // namespace search
<|endoftext|>


<commit_before><commit_msg>Added comments.<commit_after><|endoftext|>


<commit_before>//GP.cpp
#include "GP.hpp"

#include <cstdlib>
#include <iostream>

GP::GP(int popSize, int maxDepth, int numberOfXs){

    this->popSize = popSize;
    this->maxDepth = maxDepth;
    this->numberOfXs = numberOfXs;

    ramped_halfhalf();
}

GP::~GP(){
    for(int i=population.size() -1; i>=0; i--) {
        population.pop_back();
    }
}

void GP::ramped_halfhalf(){

    for (int i=1; i< (popSize+1); i++){
        population.push_back(new Individual(i%2==0, maxDepth, numberOfXs));
        if (i % (popSize/5)==0) this->maxDepth= this->maxDepth + 1;
    }
}

void GP::print_GP_d(){
    for (int i=0; i<population.size(); i++){
        population[i]->print_expression_d();
        std::cout << std::endl;
    }
}
<commit_msg>1.2 Funções de print<commit_after>//GP.cpp
#include "GP.hpp"

#include <cstdlib>
#include <iostream>

GP::GP(int popSize, int maxDepth, int numberOfXs){

    this->popSize = popSize;
    this->maxDepth = maxDepth;
    this->numberOfXs = numberOfXs;

    ramped_halfhalf();
}

GP::~GP(){
    for(int i=population.size() -1; i>=0; i--) {
        population.pop_back();
    }
}

void GP::ramped_halfhalf(){

    for (int i=1; i< (popSize+1); i++){
        population.push_back(new Individual(i%2==0, maxDepth, numberOfXs));
        if (i % (popSize/5)==0) this->maxDepth= this->maxDepth + 1;
    }
}

void GP::print_GP_d(){
    for (int i=0; i<population.size(); i++){
        population[i]->print_expression_d();
        std::cout << std::endl;
    }
}

void GP::print_GP_fitness_d(){
    for (int i=0; i<popSize; i++){
        population[i]->print_fitness_d();
    }
}

void GP::calculate_fitness(std::vector<utils::DataPoint> points){
    for (int i=0; i<popSize; i++){
        population[i]->fitness(points);
    }
}
<|endoftext|>


<commit_before>#pragma once

#include <QCryptographicHash>
#include <QJsonValue>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QPair>
#include <QString>
#include <QVector>
#include <QWidget>
#include <atomic>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
class CommaApi : public QObject {
  Q_OBJECT
public:
  static QByteArray rsa_sign(QByteArray data);
  static QString create_jwt(QVector<QPair<QString, QJsonValue>> payloads, int expiry = 60);
  static QString create_jwt();
private:
  QNetworkAccessManager* networkAccessManager;
};

/**
 * Makes repeated requests to the request endpoint.
 */
class RequestRepeater : public QObject {
  Q_OBJECT
public:
  explicit RequestRepeater(QWidget* parent, QString requestURL, int period = 10, QVector<QPair<QString, QJsonValue>> payloads = *(new QVector<QPair<QString, QJsonValue>>()), bool disableWithScreen = true);
  bool active = true;
private:
  bool disableWithScreen;
  QNetworkReply* reply;
  QNetworkAccessManager* networkAccessManager;
  QTimer* networkTimer;
  std::atomic<bool> aborted = false; // Not 100% sure we need atomic
  void sendRequest(QString requestURL, QVector<QPair<QString, QJsonValue>> payloads);
private slots:
  void requestTimeout();
  void requestFinished();
signals:
  void receivedResponse(QString response);
  void failedResponse(QString errorString);
};
<commit_msg>qt: default token validity 1 hour<commit_after>#pragma once

#include <QCryptographicHash>
#include <QJsonValue>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QPair>
#include <QString>
#include <QVector>
#include <QWidget>
#include <atomic>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
class CommaApi : public QObject {
  Q_OBJECT
public:
  static QByteArray rsa_sign(QByteArray data);
  static QString create_jwt(QVector<QPair<QString, QJsonValue>> payloads, int expiry=3600);
  static QString create_jwt();
private:
  QNetworkAccessManager* networkAccessManager;
};

/**
 * Makes repeated requests to the request endpoint.
 */
class RequestRepeater : public QObject {
  Q_OBJECT
public:
  explicit RequestRepeater(QWidget* parent, QString requestURL, int period = 10, QVector<QPair<QString, QJsonValue>> payloads = *(new QVector<QPair<QString, QJsonValue>>()), bool disableWithScreen = true);
  bool active = true;
private:
  bool disableWithScreen;
  QNetworkReply* reply;
  QNetworkAccessManager* networkAccessManager;
  QTimer* networkTimer;
  std::atomic<bool> aborted = false; // Not 100% sure we need atomic
  void sendRequest(QString requestURL, QVector<QPair<QString, QJsonValue>> payloads);
private slots:
  void requestTimeout();
  void requestFinished();
signals:
  void receivedResponse(QString response);
  void failedResponse(QString errorString);
};
<|endoftext|>


<commit_before>
// Op.cpp
/*
 * Copyright (c) 2009, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include <stdafx.h>
#include "Op.h"
#include "interface/PropertyInt.h"
#include "interface/PropertyString.h"
#include "interface/PropertyCheck.h"
#include "interface/PropertyChoice.h"
#include "interface/Tool.h"
#include "tinyxml/tinyxml.h"
#include "HeeksCNCTypes.h"
#include "CTool.h"
#include "PythonStuff.h"
#include "CNCConfig.h"
#include "MachineState.h"
#include "Program.h"
#ifdef HEEKSCNC
#include "Fixtures.h"
#define FIND_FIRST_TOOL CTool::FindFirstByType
#define FIND_ALL_TOOLS CTool::FindAllTools
#define MACHINE_STATE_TOOL(t) pMachineState->Tool(t)
#else
#define FIND_FIRST_TOOL heeksCNC->FindFirstToolByType
#define FIND_ALL_TOOLS heeksCNC->FindAllTools
#define MACHINE_STATE_TOOL(t) heeksCNC->MachineStateTool(pMachineState, t)
#endif

#include <iterator>
#include <vector>

const wxBitmap& COp::GetInactiveIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/noentry.png")));
	return *icon;
}

void COp::WriteBaseXML(TiXmlElement *element)
{
	if(m_comment.Len() > 0)element->SetAttribute("comment", m_comment.utf8_str());
	element->SetAttribute("active", m_active);
	element->SetAttribute("title", m_title.utf8_str());
	element->SetAttribute("execution_order", m_execution_order);
	element->SetAttribute("tool_number", m_tool_number);

	ObjList::WriteBaseXML(element);
}

void COp::ReadBaseXML(TiXmlElement* element)
{
	const char* comment = element->Attribute("comment");
	if(comment)m_comment.assign(Ctt(comment));
	const char* active = element->Attribute("active");
	if(active)
	{
		int int_active;
		element->Attribute("active", &int_active);
		m_active = (int_active != 0);
	}
	else
	{
        m_active = true;
	}

	const char* title = element->Attribute("title");
	if(title)m_title = wxString(Ctt(title));

	if (element->Attribute("execution_order") != NULL)
	{
		m_execution_order = atoi(element->Attribute("execution_order"));
	} // End if - then
	else
	{
		m_execution_order = 0;
	} // End if - else

	if (element->Attribute("tool_number") != NULL)
	{
		m_tool_number = atoi(element->Attribute("tool_number"));
	} // End if - then
	else
	{
		m_tool_number = 0;
	} // End if - else

	ObjList::ReadBaseXML(element);
}

static void on_set_comment(const wxChar* value, HeeksObj* object){((COp*)object)->m_comment = value;}
static void on_set_active(bool value, HeeksObj* object){((COp*)object)->m_active = value;heeksCAD->Changed();}
static void on_set_execution_order(int value, HeeksObj* object){((COp*)object)->m_execution_order = value;heeksCAD->Changed();}

static void on_set_tool_number(int zero_based_choice, HeeksObj* object)
{
	if (zero_based_choice < 0) return;	// An error has occured.

	std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

	if ((zero_based_choice >= int(0)) && (zero_based_choice <= int(tools.size()-1)))
	{
                ((COp *)object)->m_tool_number = tools[zero_based_choice].first;	// Convert the choice offset to the tool number for that choice
	} // End if - then

	((COp*)object)->WriteDefaultValues();

} // End on_set_tool_number() routine

void COp::GetProperties(std::list<Property *> *list)
{
	list->push_back(new PropertyString(_("comment"), m_comment, this, on_set_comment));
	list->push_back(new PropertyCheck(_("active"), m_active, this, on_set_active));
	list->push_back(new PropertyInt(_("execution_order"), m_execution_order, this, on_set_execution_order));

	if(UsesTool()){
		std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

		int choice = 0;
                std::list< wxString > choices;
		for (std::vector< std::pair< int, wxString > >::size_type i=0; i<tools.size(); i++)
		{
                	choices.push_back(tools[i].second);

			if (m_tool_number == tools[i].first)
			{
                		choice = int(i);
			} // End if - then
		} // End for

		list->push_back(new PropertyChoice(_("tool"), choices, choice, this, on_set_tool_number));
	}

	ObjList::GetProperties(list);
}

COp & COp::operator= ( const COp & rhs )
{
	if (this != &rhs)
	{
		// In the case of machine operations, the child objects are all used
		// for reference (position etc.) only.  When we duplicate the machine
		// operation, we don't want to duplicate these reference (child)
		// objects too.
		// To this end, we want to copy the m_objects list without duplicating the
		// objects they point to.  i.e. don't call the ObjList::operator=( rhs ) method.

		m_objects.clear();
		for (HeeksObj *child = ((ObjList &)rhs).GetFirstChild(); child != NULL; child = ((ObjList &)rhs).GetNextChild())
		{
			m_objects.push_back( child );
		} // End for

		HeeksObj::operator=(rhs);	// We need to call this as we've skipped over the ObjList::operator=() method
									// which would normally have called it for us.

		m_comment = rhs.m_comment;
		m_active = rhs.m_active;
		m_title = rhs.m_title;
		m_execution_order = rhs.m_execution_order;
		m_tool_number = rhs.m_tool_number;
		m_operation_type = rhs.m_operation_type;
	}

	return(*this);
}

// Don't call the ObjList() constructor here as the duplication is
// handled in an unusual way by the assignment operator.
COp::COp( const COp & rhs ) // : ObjList(rhs)
{
	*this = rhs;	// Call the assignment operator.
}

void COp::glCommands(bool select, bool marked, bool no_color)
{
	ObjList::glCommands(select, marked, no_color);
}

void COp::WriteDefaultValues()
{
	CNCConfig config(GetTypeString());
	config.Write(_T("Tool"), m_tool_number);
}

void COp::ReadDefaultValues()
{
	if (m_tool_number <= 0)
	{
		// The tool number hasn't been assigned from above.  Set some reasonable
		// defaults.

		CNCConfig config(GetTypeString());

		// assume that default.tooltable contains tools with IDs:
		// 1 drill
		// 2 centre drill
		// 3 end mill
		// 4 slot drill
		// 5 ball end mill
		// 6 chamfering bit
		// 7 turn tool

		int default_tool = 0;
		switch(m_operation_type)
		{
		case DrillingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eDrill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eCentreDrill );
			break;
		case AdaptiveType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ProfileType:
		case PocketType:
		case RaftType:
		case CounterBoreType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ZigZagType:
		case WaterlineType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			break;
		case TurnRoughType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTurningTool );
			break;
        case LocatingType:
		case ProbeCentreType:
		case ProbeEdgeType:
		case ProbeGridType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTouchProbe );
			break;
        case ChamferType:
        case InlayType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eChamfer );
			break;

        case TappingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTapTool );
			break;

		default:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = 4;
			break;
		}
		config.Read(_T("Tool"), &m_tool_number, default_tool);
	} // End if - then
}

/**
    Change tools (if necessary) and assign any private fixtures.
 */
Python COp::AppendTextToProgram(CMachineState *pMachineState )
{
    Python python;

	if(m_comment.Len() > 0)
	{
		python << _T("comment(") << PythonString(m_comment) << _T(")\n");
	}

	if(UsesTool())python << MACHINE_STATE_TOOL(m_tool_number);  // Select the correct  tool.

#ifdef HEEKSCNC
	// Check to see if this operation has its own fixture settings.  If so, change to that fixture now.
	for (HeeksObj *ob = GetFirstChild(); ob != NULL; ob = GetNextChild())
	{
		if (ob->GetType() == FixtureType)
		{
			CFixture *pFixture = (CFixture *) ob;
			python << pMachineState->Fixture(*pFixture);		// Change fixtures.
			break;
		}
	}
#endif

	return(python);
}

void COp::OnEditString(const wxChar* str){
	m_title.assign(str);
	heeksCAD->Changed();
}

#ifdef HEEKSCNC
class AddFixture: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Add Fixture");}
	void Run()
	{
		CProgram* program = theApp.m_program;
        if (program->Fixtures()->GetNextFixture() > 0)
        {
            CFixture::eCoordinateSystemNumber_t coordinate_system_number = CFixture::eCoordinateSystemNumber_t(program->Fixtures()->GetNextFixture());

            CFixture *new_object = new CFixture( NULL, coordinate_system_number, program->m_machine.m_safety_height_defined, program->m_machine.m_safety_height );
            m_pThis->Add(new_object, NULL);
            heeksCAD->ClearMarkedList();
            heeksCAD->Mark(new_object);
        } // End if - then
        else
        {
            wxMessageBox(_T("There are no more coordinate systems available"));
        } // End if - else
	}
	wxString BitmapPath(){ return _T("fixture");}
	wxString previous_path;
	COp *m_pThis;

public:
	void Set( COp *pOperation ) { m_pThis = pOperation; }
};

static AddFixture add_fixture;
#endif

void COp::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
    ObjList::GetTools( t_list, p );

#ifdef HEEKSCNC
	// See if this operation already has a child fixture.  If so, don't add a second one.
	unsigned int num_private_fixtures = 0;
	for (HeeksObj *child = GetFirstChild(); (child != NULL); child = GetNextChild())
	{
		if (child->GetType() == FixtureType) num_private_fixtures++;
	} // End for

	if (num_private_fixtures < MaxNumberOfPrivateFixtures())
	{
		add_fixture.Set(this);
		t_list->push_back(&add_fixture);
	} // End if - then
#endif
}

/* virtual */ std::list<CFixture> COp::PrivateFixtures()
{
    std::list<CFixture> fixtures;

    for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
    {
        if (child->GetType() == FixtureType)
        {
            fixtures.push_back( *((CFixture *) child) );
        }
    } // End for

    return(fixtures);
} // End PrivateFixtures() method

bool COp::operator==(const COp & rhs) const
{
	if (m_comment != rhs.m_comment) return(false);
	if (m_active != rhs.m_active) return(false);
	if (m_title != rhs.m_title) return(false);
	if (m_execution_order != rhs.m_execution_order) return(false);
	if (m_tool_number != rhs.m_tool_number) return(false);
	if (m_operation_type != rhs.m_operation_type) return(false);

	return(ObjList::operator==(rhs));
}

<commit_msg>Added check for the older name 'cutting_tool_number' as well as the new 'tool_number' names.  The older files were not reading the tool number values.<commit_after>
// Op.cpp
/*
 * Copyright (c) 2009, Dan Heeks
 * This program is released under the BSD license. See the file COPYING for
 * details.
 */

#include <stdafx.h>
#include "Op.h"
#include "interface/PropertyInt.h"
#include "interface/PropertyString.h"
#include "interface/PropertyCheck.h"
#include "interface/PropertyChoice.h"
#include "interface/Tool.h"
#include "tinyxml/tinyxml.h"
#include "HeeksCNCTypes.h"
#include "CTool.h"
#include "PythonStuff.h"
#include "CNCConfig.h"
#include "MachineState.h"
#include "Program.h"
#ifdef HEEKSCNC
#include "Fixtures.h"
#define FIND_FIRST_TOOL CTool::FindFirstByType
#define FIND_ALL_TOOLS CTool::FindAllTools
#define MACHINE_STATE_TOOL(t) pMachineState->Tool(t)
#else
#define FIND_FIRST_TOOL heeksCNC->FindFirstToolByType
#define FIND_ALL_TOOLS heeksCNC->FindAllTools
#define MACHINE_STATE_TOOL(t) heeksCNC->MachineStateTool(pMachineState, t)
#endif

#include <iterator>
#include <vector>

const wxBitmap& COp::GetInactiveIcon()
{
	static wxBitmap* icon = NULL;
	if(icon == NULL)icon = new wxBitmap(wxImage(theApp.GetResFolder() + _T("/icons/noentry.png")));
	return *icon;
}

void COp::WriteBaseXML(TiXmlElement *element)
{
	if(m_comment.Len() > 0)element->SetAttribute("comment", m_comment.utf8_str());
	element->SetAttribute("active", m_active);
	element->SetAttribute("title", m_title.utf8_str());
	element->SetAttribute("execution_order", m_execution_order);
	element->SetAttribute("tool_number", m_tool_number);

	ObjList::WriteBaseXML(element);
}

void COp::ReadBaseXML(TiXmlElement* element)
{
	const char* comment = element->Attribute("comment");
	if(comment)m_comment.assign(Ctt(comment));
	const char* active = element->Attribute("active");
	if(active)
	{
		int int_active;
		element->Attribute("active", &int_active);
		m_active = (int_active != 0);
	}
	else
	{
        m_active = true;
	}

	const char* title = element->Attribute("title");
	if(title)m_title = wxString(Ctt(title));

	if (element->Attribute("execution_order") != NULL)
	{
		m_execution_order = atoi(element->Attribute("execution_order"));
	} // End if - then
	else
	{
		m_execution_order = 0;
	} // End if - else

	if (element->Attribute("tool_number") != NULL)
	{
		m_tool_number = atoi(element->Attribute("tool_number"));
	} // End if - then
	else
	{
	    // The older files used to call this attribute 'cutting_tool_number'.  Look for this old
	    // name if we can't find the new one.
	    if (element->Attribute("cutting_tool_number") != NULL)
        {
            m_tool_number = atoi(element->Attribute("cutting_tool_number"));
        } // End if - then
        else
        {
            m_tool_number = 0;
        } // End if - else
	} // End if - else

	ObjList::ReadBaseXML(element);
}

static void on_set_comment(const wxChar* value, HeeksObj* object){((COp*)object)->m_comment = value;}
static void on_set_active(bool value, HeeksObj* object){((COp*)object)->m_active = value;heeksCAD->Changed();}
static void on_set_execution_order(int value, HeeksObj* object){((COp*)object)->m_execution_order = value;heeksCAD->Changed();}

static void on_set_tool_number(int zero_based_choice, HeeksObj* object)
{
	if (zero_based_choice < 0) return;	// An error has occured.

	std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

	if ((zero_based_choice >= int(0)) && (zero_based_choice <= int(tools.size()-1)))
	{
                ((COp *)object)->m_tool_number = tools[zero_based_choice].first;	// Convert the choice offset to the tool number for that choice
	} // End if - then

	((COp*)object)->WriteDefaultValues();

} // End on_set_tool_number() routine

void COp::GetProperties(std::list<Property *> *list)
{
	list->push_back(new PropertyString(_("comment"), m_comment, this, on_set_comment));
	list->push_back(new PropertyCheck(_("active"), m_active, this, on_set_active));
	list->push_back(new PropertyInt(_("execution_order"), m_execution_order, this, on_set_execution_order));

	if(UsesTool()){
		std::vector< std::pair< int, wxString > > tools = FIND_ALL_TOOLS();

		int choice = 0;
                std::list< wxString > choices;
		for (std::vector< std::pair< int, wxString > >::size_type i=0; i<tools.size(); i++)
		{
                	choices.push_back(tools[i].second);

			if (m_tool_number == tools[i].first)
			{
                		choice = int(i);
			} // End if - then
		} // End for

		list->push_back(new PropertyChoice(_("tool"), choices, choice, this, on_set_tool_number));
	}

	ObjList::GetProperties(list);
}

COp & COp::operator= ( const COp & rhs )
{
	if (this != &rhs)
	{
		// In the case of machine operations, the child objects are all used
		// for reference (position etc.) only.  When we duplicate the machine
		// operation, we don't want to duplicate these reference (child)
		// objects too.
		// To this end, we want to copy the m_objects list without duplicating the
		// objects they point to.  i.e. don't call the ObjList::operator=( rhs ) method.

		m_objects.clear();
		for (HeeksObj *child = ((ObjList &)rhs).GetFirstChild(); child != NULL; child = ((ObjList &)rhs).GetNextChild())
		{
			m_objects.push_back( child );
		} // End for

		HeeksObj::operator=(rhs);	// We need to call this as we've skipped over the ObjList::operator=() method
									// which would normally have called it for us.

		m_comment = rhs.m_comment;
		m_active = rhs.m_active;
		m_title = rhs.m_title;
		m_execution_order = rhs.m_execution_order;
		m_tool_number = rhs.m_tool_number;
		m_operation_type = rhs.m_operation_type;
	}

	return(*this);
}

// Don't call the ObjList() constructor here as the duplication is
// handled in an unusual way by the assignment operator.
COp::COp( const COp & rhs ) // : ObjList(rhs)
{
	*this = rhs;	// Call the assignment operator.
}

void COp::glCommands(bool select, bool marked, bool no_color)
{
	ObjList::glCommands(select, marked, no_color);
}

void COp::WriteDefaultValues()
{
	CNCConfig config(GetTypeString());
	config.Write(_T("Tool"), m_tool_number);
}

void COp::ReadDefaultValues()
{
	if (m_tool_number <= 0)
	{
		// The tool number hasn't been assigned from above.  Set some reasonable
		// defaults.

		CNCConfig config(GetTypeString());

		// assume that default.tooltable contains tools with IDs:
		// 1 drill
		// 2 centre drill
		// 3 end mill
		// 4 slot drill
		// 5 ball end mill
		// 6 chamfering bit
		// 7 turn tool

		int default_tool = 0;
		switch(m_operation_type)
		{
		case DrillingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eDrill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eCentreDrill );
			break;
		case AdaptiveType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ProfileType:
		case PocketType:
		case RaftType:
		case CounterBoreType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			break;
		case ZigZagType:
		case WaterlineType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			break;
		case TurnRoughType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTurningTool );
			break;
        case LocatingType:
		case ProbeCentreType:
		case ProbeEdgeType:
		case ProbeGridType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTouchProbe );
			break;
        case ChamferType:
        case InlayType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eChamfer );
			break;

        case TappingType:
			default_tool = FIND_FIRST_TOOL( CToolParams::eTapTool );
			break;

		default:
			default_tool = FIND_FIRST_TOOL( CToolParams::eEndmill );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eSlotCutter );
			if (default_tool <= 0) default_tool = FIND_FIRST_TOOL( CToolParams::eBallEndMill );
			if (default_tool <= 0) default_tool = 4;
			break;
		}
		config.Read(_T("Tool"), &m_tool_number, default_tool);
	} // End if - then
}

/**
    Change tools (if necessary) and assign any private fixtures.
 */
Python COp::AppendTextToProgram(CMachineState *pMachineState )
{
    Python python;

	if(m_comment.Len() > 0)
	{
		python << _T("comment(") << PythonString(m_comment) << _T(")\n");
	}

	if(UsesTool())python << MACHINE_STATE_TOOL(m_tool_number);  // Select the correct  tool.

#ifdef HEEKSCNC
	// Check to see if this operation has its own fixture settings.  If so, change to that fixture now.
	for (HeeksObj *ob = GetFirstChild(); ob != NULL; ob = GetNextChild())
	{
		if (ob->GetType() == FixtureType)
		{
			CFixture *pFixture = (CFixture *) ob;
			python << pMachineState->Fixture(*pFixture);		// Change fixtures.
			break;
		}
	}
#endif

	return(python);
}

void COp::OnEditString(const wxChar* str){
	m_title.assign(str);
	heeksCAD->Changed();
}

#ifdef HEEKSCNC
class AddFixture: public Tool{
	// Tool's virtual functions
	const wxChar* GetTitle(){return _("Add Fixture");}
	void Run()
	{
		CProgram* program = theApp.m_program;
        if (program->Fixtures()->GetNextFixture() > 0)
        {
            CFixture::eCoordinateSystemNumber_t coordinate_system_number = CFixture::eCoordinateSystemNumber_t(program->Fixtures()->GetNextFixture());

            CFixture *new_object = new CFixture( NULL, coordinate_system_number, program->m_machine.m_safety_height_defined, program->m_machine.m_safety_height );
            m_pThis->Add(new_object, NULL);
            heeksCAD->ClearMarkedList();
            heeksCAD->Mark(new_object);
        } // End if - then
        else
        {
            wxMessageBox(_T("There are no more coordinate systems available"));
        } // End if - else
	}
	wxString BitmapPath(){ return _T("fixture");}
	wxString previous_path;
	COp *m_pThis;

public:
	void Set( COp *pOperation ) { m_pThis = pOperation; }
};

static AddFixture add_fixture;
#endif

void COp::GetTools(std::list<Tool*>* t_list, const wxPoint* p)
{
    ObjList::GetTools( t_list, p );

#ifdef HEEKSCNC
	// See if this operation already has a child fixture.  If so, don't add a second one.
	unsigned int num_private_fixtures = 0;
	for (HeeksObj *child = GetFirstChild(); (child != NULL); child = GetNextChild())
	{
		if (child->GetType() == FixtureType) num_private_fixtures++;
	} // End for

	if (num_private_fixtures < MaxNumberOfPrivateFixtures())
	{
		add_fixture.Set(this);
		t_list->push_back(&add_fixture);
	} // End if - then
#endif
}

/* virtual */ std::list<CFixture> COp::PrivateFixtures()
{
    std::list<CFixture> fixtures;

    for (HeeksObj *child = GetFirstChild(); child != NULL; child = GetNextChild())
    {
        if (child->GetType() == FixtureType)
        {
            fixtures.push_back( *((CFixture *) child) );
        }
    } // End for

    return(fixtures);
} // End PrivateFixtures() method

bool COp::operator==(const COp & rhs) const
{
	if (m_comment != rhs.m_comment) return(false);
	if (m_active != rhs.m_active) return(false);
	if (m_title != rhs.m_title) return(false);
	if (m_execution_order != rhs.m_execution_order) return(false);
	if (m_tool_number != rhs.m_tool_number) return(false);
	if (m_operation_type != rhs.m_operation_type) return(false);

	return(ObjList::operator==(rhs));
}

<|endoftext|>