<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "CustomWeapon.h"

/* system headers */
#include <sstream>
#include <string>

/* local implementation headers */
#include "WorldWeapons.h"

/* FIXME - external dependancies */
extern WorldWeapons  wWeapons;

TimeKeeper CustomWeapon::sync = TimeKeeper::getCurrent();

const float CustomWeapon::minWeaponDelay = 0.1f;

CustomWeapon::CustomWeapon()
{
  pos[0] = pos[1] = pos[2] = 0.0f;
  rotation = 0.0f;
  size[0] = size[1] = size[2] = 1.0f;
  initdelay = 10.0f;
  delay.push_back(10.0f);
  type = Flags::Null;
}

bool CustomWeapon::read(const char *cmd, std::istream& input) {
  if (strcmp(cmd, "initdelay") == 0) {
    input >> initdelay;
  }
  else if (strcmp(cmd, "delay") == 0) {
    std::string args;
    float d;

    delay.clear();
    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> d) {
      if (d < minWeaponDelay) {
	std::cout << "skipping weapon delay of " << d << " seconds" << std::endl;
	continue;
      }
      else {
	delay.push_back(d);
      }
    }
    input.putback('\n');
    if (delay.size() == 0)
      return false;
  }
  else if (strcmp(cmd, "type") == 0) {
    std::string abbv;
    input >> abbv;
    type = Flag::getDescFromAbbreviation(abbv.c_str());
    if (type == NULL)
      return false;
  }
  else if (!WorldFileLocation::read(cmd, input))
      return false;

  return true;
}

void CustomWeapon::writeToWorld(WorldInfo* world) const {
  world->addWeapon(type, pos, rotation, initdelay, delay, sync);
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>remove unused extern<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "CustomWeapon.h"

/* system headers */
#include <sstream>
#include <string>

/* local implementation headers */
#include "WorldWeapons.h"

TimeKeeper CustomWeapon::sync = TimeKeeper::getCurrent();

const float CustomWeapon::minWeaponDelay = 0.1f;

CustomWeapon::CustomWeapon()
{
  pos[0] = pos[1] = pos[2] = 0.0f;
  rotation = 0.0f;
  size[0] = size[1] = size[2] = 1.0f;
  initdelay = 10.0f;
  delay.push_back(10.0f);
  type = Flags::Null;
}

bool CustomWeapon::read(const char *cmd, std::istream& input) {
  if (strcmp(cmd, "initdelay") == 0) {
    input >> initdelay;
  }
  else if (strcmp(cmd, "delay") == 0) {
    std::string args;
    float d;

    delay.clear();
    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> d) {
      if (d < minWeaponDelay) {
	std::cout << "skipping weapon delay of " << d << " seconds" << std::endl;
	continue;
      }
      else {
	delay.push_back(d);
      }
    }
    input.putback('\n');
    if (delay.size() == 0)
      return false;
  }
  else if (strcmp(cmd, "type") == 0) {
    std::string abbv;
    input >> abbv;
    type = Flag::getDescFromAbbreviation(abbv.c_str());
    if (type == NULL)
      return false;
  }
  else if (!WorldFileLocation::read(cmd, input))
      return false;

  return true;
}

void CustomWeapon::writeToWorld(WorldInfo* world) const {
  world->addWeapon(type, pos, rotation, initdelay, delay, sync);
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before><commit_msg>#99549# check used columns<commit_after><|endoftext|>


<commit_before><commit_msg>css.sdbc.XResultSet.getRow return type is long<commit_after><|endoftext|>


<commit_before>#include "gtest/gtest.h"

#include "gpac/module.h"
#include "gpac/modules/codec.h"
#include "gpac/modules/service.h"
#include "gpac/internal/terminal_dev.h"

using namespace std;

string signals_fld;
string modules_fld;
string preserved_fld;
string accessors_fld;

GF_ModuleManager *modules;
GF_Config *config;
GF_MediaDecoder* ifce_acc;
GF_Channel *ch;
GF_NetworkCommand com;
GF_ClientService net_service;

static void img_on_connect(GF_ClientService *service, LPNETCHANNEL netch, GF_Err err)
{
	service->ifce->GetServiceDescriptor(service->ifce, 1, "");
}

static void img_on_disconnect(GF_ClientService *service, LPNETCHANNEL netch, GF_Err response)
{
	gf_es_del(ch);
}

static void img_on_command(GF_ClientService *service, GF_NetworkCommand *com, GF_Err response)
{

}

static void img_on_data_packet(GF_ClientService *service, LPNETCHANNEL netch, char *data, u32 data_size, GF_SLHeader *hdr, GF_Err reception_status){

}

static void img_on_media_add(GF_ClientService *service, GF_Descriptor *media_desc, Bool no_scene_check)
{

	if (media_desc) {
		GF_ESD *esd;
		u32 e2;
		GF_ObjectDescriptor *odm;

		odm = (GF_ObjectDescriptor *)media_desc;
		esd = (GF_ESD *)gf_list_get(odm->ESDescriptors, 0);
		ch = gf_es_new(esd);
		com.base.on_channel = ch;

		ASSERT_EQ(service->ifce->ConnectChannel(service->ifce, ch, "ES_ID=1", (Bool)esd->decoderConfig->upstream), GF_OK);
		ASSERT_EQ(service->ifce->ServiceCommand(service->ifce, &com), GF_OK);

		ASSERT_EQ(ifce_acc->CanHandleStream((GF_BaseDecoder*)ifce_acc, GF_STREAM_VISUAL, esd, 0), GF_CODEC_SUPPORTED);
		ASSERT_EQ(ifce_acc->AttachStream((GF_BaseDecoder*)ifce_acc, esd), GF_OK);
	}

}

void getImgOutput(const char* url, char* service, char* decoder, char** dataOut, u32* outDataLength){
	GF_Descriptor *desc;
	GF_Err e, state;
	GF_SLHeader slh;
	u32 inDataLength = 0;
	Bool comp, is_new_data;
	char *dataIn = NULL;

	u32 od_type = 0;
	char *ext, *redirect_url;
	char *sub_url=NULL;

	*outDataLength = 0;
	*dataOut = 0;

	ifce_acc = (GF_MediaDecoder*)gf_modules_load_interface_by_name(modules, decoder, GF_MEDIA_DECODER_INTERFACE);
	ASSERT_TRUE(ifce_acc);
	GF_InputService* ifce_isom = (GF_InputService*)gf_modules_load_interface_by_name(modules, service, GF_NET_CLIENT_INTERFACE);
	ASSERT_TRUE(ifce_acc);

	net_service.fn_connect_ack = img_on_connect;
	net_service.fn_disconnect_ack = img_on_disconnect;
	net_service.fn_command = img_on_command;
	net_service.fn_data_packet = img_on_data_packet;
	net_service.fn_add_media = img_on_media_add;
	net_service.ifce = ifce_isom;

	/* Connecting */
	ASSERT_EQ(ifce_isom->ConnectService(ifce_isom, &net_service, url), GF_OK);

	/* Decoding */
	memset(&slh, 0, sizeof(GF_SLHeader));
	ASSERT_EQ(ifce_isom->ChannelGetSLP(ifce_isom, ch, (char **)&dataIn, &inDataLength, &slh, &comp, &state, &is_new_data), GF_OK);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_BUFFER_TOO_SMALL);

	/* Decoding */
	*dataOut = (char*)malloc(*outDataLength);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_OK);

	gf_modules_close_interface((GF_BaseInterface *)ifce_acc);
	gf_modules_close_interface((GF_BaseInterface *)ifce_isom);
}

void getAccImgOutput(const char* file_url, const char* accessor_url, char** dataOut, u32* outDataLength) {
	GF_Descriptor *desc;
	GF_Err e, state;
	GF_SLHeader slh;
	u32 inDataLength = 0;
	Bool comp, is_new_data;
	char *dataIn = NULL;
	char* service = "GPAC Image Reader";
	char* decoder = "Accessor dec";
	u32 od_type = 0;
	char *ext, *redirect_url;
	char *sub_url = NULL;

	*outDataLength = 0;
	*dataOut = 0;

	ifce_acc = (GF_MediaDecoder*)gf_modules_load_interface_by_name(modules, decoder, GF_MEDIA_DECODER_INTERFACE);
	ASSERT_TRUE(ifce_acc);
	GF_InputService* ifce_isom = (GF_InputService*)gf_modules_load_interface_by_name(modules, service, GF_NET_CLIENT_INTERFACE);
	ASSERT_TRUE(ifce_acc);

	net_service.fn_connect_ack = img_on_connect;
	net_service.fn_disconnect_ack = img_on_disconnect;
	net_service.fn_command = img_on_command;
	net_service.fn_data_packet = img_on_data_packet;
	net_service.fn_add_media = img_on_media_add;
	net_service.ifce = ifce_isom;

	/* Connecting */
	ASSERT_EQ(ifce_isom->ConnectService(ifce_isom, &net_service, file_url), GF_OK);

	/* Decoding */
	memset(&slh, 0, sizeof(GF_SLHeader));
	ASSERT_EQ(ifce_isom->ChannelGetSLP(ifce_isom, ch, (char **)&dataIn, &inDataLength, &slh, &comp, &state, &is_new_data), GF_OK);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_BUFFER_TOO_SMALL);

	/* Decoding */
	gf_cfg_set_key(config, "Accessor", "File", accessor_url);
	*dataOut = (char*)malloc(*outDataLength);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_OK);

	gf_modules_close_interface((GF_BaseInterface *)ifce_acc);
	gf_modules_close_interface((GF_BaseInterface *)ifce_isom);
}

TEST(File, JPG_PROGRESSIVE) {
	char *accData = NULL;
	char *jpegData = NULL;
	u32 accDataLength = 0;
	u32 jpegDataLength = 0;
	string inFile = signals_fld;
	string preservedFile = preserved_fld;
	int comp;

	/* Set file in*/
	inFile.append("Freedom_progressive.jpg");

	/* Set preserved file */
	preservedFile.append("Freedom_progressive.jpg.bvr");

	getImgOutput(inFile.c_str(), "GPAC Image Reader", "GPAC Image Decoder", &jpegData, &jpegDataLength);
	getImgOutput(inFile.c_str(), "GPAC IsoMedia Reader", "Accessor dec", &accData, &accDataLength);

	/* Compare result */
	ASSERT_EQ(jpegDataLength, accDataLength);
	comp = memcmp(jpegData, accData, accDataLength);
	printf("Value of decoder comparison is %d", comp);
}

TEST(File, DNG) {
	char *accData = NULL;
	char *jpegData = NULL;
	u32 accDataLength = 0;
	u32 jpegDataLength = 0;
	string inFile = signals_fld;
	string accessorFile = accessors_fld;
	int comp;

	/* Set file in*/
	inFile.append("ATK_SFS_almost_no_knead_bread-32.dng");
	accessorFile.append("dng_entry_0.1.bc");

	getImgOutput(inFile.c_str(), "GPAC Image Reader", "GPAC Image Decoder", &jpegData, &jpegDataLength);
	getAccImgOutput(inFile.c_str(), accessorFile.c_str(), &accData, &accDataLength);

	/* Compare result */
	ASSERT_EQ(jpegDataLength, accDataLength);
	comp = memcmp(jpegData, accData, accDataLength);
	printf("Value of decoder comparison is %d", comp);
}

TEST(File, JPG) {
	char *accData = NULL;
	char *jpegData = NULL;
	u32 accDataLength = 0;
	u32 jpegDataLength = 0;
	string inFile = signals_fld;
	string preservedFile = preserved_fld;
	int comp;

	/* Set file in*/
	inFile.append("Freedom.jpg");

	/* Set preserved file */
	preservedFile.append("Freedom.jpg.bvr");

	getImgOutput(inFile.c_str(), "GPAC Image Reader", "GPAC Image Decoder", &jpegData, &jpegDataLength);
	getImgOutput(preservedFile.c_str(), "GPAC IsoMedia Reader", "Accessor dec", &accData, &accDataLength);

	/* Compare result */
	ASSERT_EQ(jpegDataLength, accDataLength);
	comp = memcmp(jpegData, accData, accDataLength);
	printf("Value of decoder comparison is %d", comp);
}

int main(int argc, char **argv) {
	::testing::InitGoogleTest(&argc, argv);

	for (int i = 1; i < argc; i++) {
		if (i + 1 != argc){
			if (strcmp("-signals", argv[i]) == 0) {
				signals_fld = argv[++i];
				std::cout << "Test signal folder set to " << signals_fld << endl;
			}
			if (strcmp("-preserved", argv[i]) == 0) {
				preserved_fld = argv[++i];
				std::cout << "Preserved signal folder set to " << preserved_fld << endl;
			}
			else if (strcmp("-modules", argv[i]) == 0) {
				modules_fld = argv[++i];
				std::cout << "Test modules folder set to " << modules_fld << endl;
			}
			else if (strcmp("-modules", argv[i]) == 0) {
				accessors_fld = argv[++i];
				std::cout << "Accessors folder set to " << accessors_fld << endl;
			}
		}
	}
	gf_sys_init(GF_FALSE);
	config = gf_cfg_init(NULL, NULL);
	modules = gf_modules_new(NULL, config);

	//test_jpg();
	return RUN_ALL_TESTS();
}
<commit_msg>Disabling unused tests<commit_after>#include "gtest/gtest.h"

#include "gpac/module.h"
#include "gpac/modules/codec.h"
#include "gpac/modules/service.h"
#include "gpac/internal/terminal_dev.h"

using namespace std;

string signals_fld;
string modules_fld;
string preserved_fld;
string accessors_fld;

GF_ModuleManager *modules;
GF_Config *config;
GF_MediaDecoder* ifce_acc;
GF_Channel *ch;
GF_NetworkCommand com;
GF_ClientService net_service;

static void img_on_connect(GF_ClientService *service, LPNETCHANNEL netch, GF_Err err)
{
	service->ifce->GetServiceDescriptor(service->ifce, 1, "");
}

static void img_on_disconnect(GF_ClientService *service, LPNETCHANNEL netch, GF_Err response)
{
	gf_es_del(ch);
}

static void img_on_command(GF_ClientService *service, GF_NetworkCommand *com, GF_Err response)
{

}

static void img_on_data_packet(GF_ClientService *service, LPNETCHANNEL netch, char *data, u32 data_size, GF_SLHeader *hdr, GF_Err reception_status){

}

static void img_on_media_add(GF_ClientService *service, GF_Descriptor *media_desc, Bool no_scene_check)
{

	if (media_desc) {
		GF_ESD *esd;
		u32 e2;
		GF_ObjectDescriptor *odm;

		odm = (GF_ObjectDescriptor *)media_desc;
		esd = (GF_ESD *)gf_list_get(odm->ESDescriptors, 0);
		ch = gf_es_new(esd);
		com.base.on_channel = ch;

		ASSERT_EQ(service->ifce->ConnectChannel(service->ifce, ch, "ES_ID=1", (Bool)esd->decoderConfig->upstream), GF_OK);
		ASSERT_EQ(service->ifce->ServiceCommand(service->ifce, &com), GF_OK);

		ASSERT_EQ(ifce_acc->CanHandleStream((GF_BaseDecoder*)ifce_acc, GF_STREAM_VISUAL, esd, 0), GF_CODEC_SUPPORTED);
		ASSERT_EQ(ifce_acc->AttachStream((GF_BaseDecoder*)ifce_acc, esd), GF_OK);
	}

}

void getImgOutput(const char* url, char* service, char* decoder, char** dataOut, u32* outDataLength){
	GF_Descriptor *desc;
	GF_Err e, state;
	GF_SLHeader slh;
	u32 inDataLength = 0;
	Bool comp, is_new_data;
	char *dataIn = NULL;

	u32 od_type = 0;
	char *ext, *redirect_url;
	char *sub_url=NULL;

	*outDataLength = 0;
	*dataOut = 0;

	ifce_acc = (GF_MediaDecoder*)gf_modules_load_interface_by_name(modules, decoder, GF_MEDIA_DECODER_INTERFACE);
	ASSERT_TRUE(ifce_acc);
	GF_InputService* ifce_isom = (GF_InputService*)gf_modules_load_interface_by_name(modules, service, GF_NET_CLIENT_INTERFACE);
	ASSERT_TRUE(ifce_acc);

	net_service.fn_connect_ack = img_on_connect;
	net_service.fn_disconnect_ack = img_on_disconnect;
	net_service.fn_command = img_on_command;
	net_service.fn_data_packet = img_on_data_packet;
	net_service.fn_add_media = img_on_media_add;
	net_service.ifce = ifce_isom;

	/* Connecting */
	ASSERT_EQ(ifce_isom->ConnectService(ifce_isom, &net_service, url), GF_OK);

	/* Decoding */
	memset(&slh, 0, sizeof(GF_SLHeader));
	ASSERT_EQ(ifce_isom->ChannelGetSLP(ifce_isom, ch, (char **)&dataIn, &inDataLength, &slh, &comp, &state, &is_new_data), GF_OK);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_BUFFER_TOO_SMALL);

	/* Decoding */
	*dataOut = (char*)malloc(*outDataLength);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_OK);

	gf_modules_close_interface((GF_BaseInterface *)ifce_acc);
	gf_modules_close_interface((GF_BaseInterface *)ifce_isom);
}

void getAccImgOutput(const char* file_url, const char* accessor_url, char** dataOut, u32* outDataLength) {
	GF_Descriptor *desc;
	GF_Err e, state;
	GF_SLHeader slh;
	u32 inDataLength = 0;
	Bool comp, is_new_data;
	char *dataIn = NULL;
	char* service = "GPAC Image Reader";
	char* decoder = "Accessor dec";
	u32 od_type = 0;
	char *ext, *redirect_url;
	char *sub_url = NULL;

	*outDataLength = 0;
	*dataOut = 0;
	gf_cfg_set_key(config, "Accessor", "File", accessor_url);

	ifce_acc = (GF_MediaDecoder*)gf_modules_load_interface_by_name(modules, decoder, GF_MEDIA_DECODER_INTERFACE);
	ASSERT_TRUE(ifce_acc);
	GF_InputService* ifce_isom = (GF_InputService*)gf_modules_load_interface_by_name(modules, service, GF_NET_CLIENT_INTERFACE);
	ASSERT_TRUE(ifce_acc);

	net_service.fn_connect_ack = img_on_connect;
	net_service.fn_disconnect_ack = img_on_disconnect;
	net_service.fn_command = img_on_command;
	net_service.fn_data_packet = img_on_data_packet;
	net_service.fn_add_media = img_on_media_add;
	net_service.ifce = ifce_isom;

	/* Connecting */
	ASSERT_EQ(ifce_isom->ConnectService(ifce_isom, &net_service, file_url), GF_OK);

	/* Decoding */
	memset(&slh, 0, sizeof(GF_SLHeader));
	ASSERT_EQ(ifce_isom->ChannelGetSLP(ifce_isom, ch, (char **)&dataIn, &inDataLength, &slh, &comp, &state, &is_new_data), GF_OK);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_BUFFER_TOO_SMALL);

	/* Decoding */
	*dataOut = (char*)malloc(*outDataLength);
	ASSERT_EQ(ifce_acc->ProcessData(ifce_acc, dataIn, inDataLength, 0, NULL, *dataOut, outDataLength, 0, 0), GF_OK);

	gf_modules_close_interface((GF_BaseInterface *)ifce_acc);
	gf_modules_close_interface((GF_BaseInterface *)ifce_isom);
}

TEST(File, DISABLED_JPG_PROGRESSIVE) {
	char *accData = NULL;
	char *jpegData = NULL;
	u32 accDataLength = 0;
	u32 jpegDataLength = 0;
	string inFile = signals_fld;
	string preservedFile = preserved_fld;
	int comp;

	/* Set file in*/
	inFile.append("Freedom_progressive.jpg");

	/* Set preserved file */
	preservedFile.append("Freedom_progressive.jpg.bvr");

	getImgOutput(inFile.c_str(), "GPAC Image Reader", "GPAC Image Decoder", &jpegData, &jpegDataLength);
	getImgOutput(inFile.c_str(), "GPAC IsoMedia Reader", "Accessor dec", &accData, &accDataLength);

	/* Compare result */
	ASSERT_EQ(jpegDataLength, accDataLength);
	comp = memcmp(jpegData, accData, accDataLength);
	printf("Value of decoder comparison is %d", comp);
}

TEST(File, DNG) {
	char *accData = NULL;
	char *jpegData = NULL;
	u32 accDataLength = 0;
	u32 jpegDataLength = 0;
	string inFile = signals_fld;
	string accessorFile = accessors_fld;
	int comp;

	/* Set file in*/
	inFile.append("ATK_SFS_almost_no_knead_bread-32.dng");
	accessorFile.append("dng_entry_0.1.bc");

	getImgOutput(inFile.c_str(), "GPAC Image Reader", "GPAC Image Decoder", &jpegData, &jpegDataLength);
	getAccImgOutput(inFile.c_str(), accessorFile.c_str(), &accData, &accDataLength);

	/* Compare result */
	ASSERT_EQ(jpegDataLength, accDataLength);
	comp = memcmp(jpegData, accData, accDataLength);
	printf("Value of decoder comparison is %d", comp);
}

TEST(File, DISABLED_JPG) {
	char *accData = NULL;
	char *jpegData = NULL;
	u32 accDataLength = 0;
	u32 jpegDataLength = 0;
	string inFile = signals_fld;
	string preservedFile = preserved_fld;
	int comp;

	/* Set file in*/
	inFile.append("Freedom.jpg");

	/* Set preserved file */
	preservedFile.append("Freedom.jpg.bvr");

	getImgOutput(inFile.c_str(), "GPAC Image Reader", "GPAC Image Decoder", &jpegData, &jpegDataLength);
	getImgOutput(preservedFile.c_str(), "GPAC IsoMedia Reader", "Accessor dec", &accData, &accDataLength);

	/* Compare result */
	ASSERT_EQ(jpegDataLength, accDataLength);
	comp = memcmp(jpegData, accData, accDataLength);
	printf("Value of decoder comparison is %d", comp);
}

int main(int argc, char **argv) {
	::testing::InitGoogleTest(&argc, argv);

	for (int i = 1; i < argc; i++) {
		if (i + 1 != argc){
			if (strcmp("--signals", argv[i]) == 0) {
				signals_fld = argv[++i];
				signals_fld.append("\\");
				std::cout << "Test signal folder set to " << signals_fld << endl;
			}
			if (strcmp("--preserved", argv[i]) == 0) {
				preserved_fld = argv[++i];
				preserved_fld.append("\\");
				std::cout << "Preserved signal folder set to " << preserved_fld << endl;
			}
			else if (strcmp("--modules", argv[i]) == 0) {
				modules_fld = argv[++i];
				modules_fld.append("\\");
				std::cout << "Test modules folder set to " << modules_fld << endl;
			}
			else if (strcmp("--accessors", argv[i]) == 0) {
				accessors_fld = argv[++i];
				accessors_fld.append("\\");
				std::cout << "Accessors folder set to " << accessors_fld << endl;
			}
		}
	}
	gf_sys_init(GF_FALSE);
	config = gf_cfg_init(NULL, NULL);
	modules = gf_modules_new(NULL, config);

	//test_jpg();
	return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "trainmonitor.h"
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QThread>

TrainMonitor::TrainMonitor()
{
#pragma message("[MKJ] Clean up when everything is done")
#pragma message("[MKJ] Look for things that would be useful in a log")

}

TrainMonitor::~TrainMonitor()
{

}

void TrainMonitor::do_run() {
	generateSectionList();
}

void TrainMonitor::do_handleOccupancy(QString section, bool state)
{
    qDebug() << "do_handleOccupancy entered";
	qDebug() << "New Occupancy Data at Monitor:" << section << " State:" << state;
	Section monitoredSection = retrieveSections(section);
	monitoredSection.setOccupancy(state);
    //if (state) Monitor(monitoredSection);
    if (state) Monitor(section);
}

void TrainMonitor::Monitor(QString section)
{
    qDebug() << endl << endl;

    for (auto section : sectionPairs)
    {
        qDebug() << "last section is: " << section.first << " current section is:" << section.second << endl;
    }

    qDebug() << endl << endl;
#pragma message("[MKJ] Will nextSection1 be enough padding for a crash scenario?")
        //Section monitorSection = es.path.getNextSection1();

    Section currentSection = retrieveSections(section);
    qDebug() << "Starting monitor ....." << endl;
    switch (currentSection.getNumOfConns())
    {
        case 1:		// Endpoint case
        {
            updateSingleConnList(currentSection);
            qDebug() << "entered endpoint monitor" << endl;
            endpointMonitor(currentSection);
            break;
        }
        case 2:		// Straight case
        {
            updateDoubleConnList(currentSection);
            qDebug() << "entered straight monitor" << endl;
            straightMonitor(currentSection);
            break;
        }
        case 3:		// Switch case
        {
            updateTripleConnList(currentSection);
            qDebug() << "entered switch monitor" << endl;
            switchMonitor(currentSection);
            break;
        }
        case 4:		// Crossover case
        {
            updateQuadConnList(currentSection);
            qDebug() << "entered crossover monitor" << endl;
            //crossoverMonitor(currentSection);
            break;
        }
        default:
        {
            qFatal("Invalid track type");
            break;
        }
    }
}

void TrainMonitor::endpointMonitor(Section sec)
{
	// Shutdown the section since the means the train is headed
    // towards the end of the track
    for (auto section : sectionPairs)
    {
        if (sec.getNode() == section.second)
        {
            if(section.first != "")
            {
                qDebug() << "Shutting off section " << section.second;
                Section shutdownSection = retrieveSections(section.second);
                QStringList shutdownList = shutdownSection.getNode().split("-");
                emit sectionOff(shutdownList[0].toInt(),shutdownList[1].toInt());
            }
        }
    }
}

void TrainMonitor::straightMonitor(Section sec)
{
    QString nextSection;
    bool found = false;

    for (auto section : sectionPairs)
    {

        qDebug() << sec.getNode() << " sec.second is:" << section.second << endl;
        if(sec.getNode() == section.second)
        {
            nextSection = getNextStraightSection(
                        retrieveSections(section.first), retrieveSections(section.second));
            found = true;
        }
    }

   /* if(!found)
    {
        qDebug() << "Shit didn't work homie!!!";
    }*/

    for(auto section : sectionPairs)
    {
        if(nextSection == section.second)
        {
            //emit trackOff();
            qDebug() << "Shutting off section " << section.second;
            Section shutdownSection = retrieveSections(section.second);
            emit sectionOff(shutdownSection.getBoardNum(),shutdownSection.getSection());
        }
    }
}

void TrainMonitor::switchMonitor(Section sec)
{
    QString monitorSection;
    QString nextSection;
    for (auto section : sectionPairs)
    {
        if(sec.getNode() == section.second)
        {
            nextSection = getNextStraightSection(
                        retrieveSections(section.first), retrieveSections(section.second));
        }

        if(nextSection != "")
        {
            switch (retrieveSections(nextSection).getNumOfConns())
            {
                case 1: {
                    //emit trackOff();
                    qDebug() << "Shutting off section " << section.second;
                    Section shutdownSection = retrieveSections(nextSection);
                    QStringList shutdownList = shutdownSection.getNode().split("-");
                    emit sectionOff(shutdownList[0].toInt(),shutdownList[1].toInt());

                    break;
                } case 2: {
                    monitorSection = getNextStraightSection(
                                retrieveSections(section.first), retrieveSections(nextSection));
                    break;
                } case 3: {
                    monitorSection = getNextStraightSection(
                                retrieveSections(section.second), retrieveSections(nextSection));
                    break;
                } case 4:
                    // TODO
                    break;
            }
        }
    }

    for (auto section : sectionPairs)
    {
        if(section.second == monitorSection)
        {
            //emit trackOff();
            qDebug() << "Shutting off section " << section.second;
            Section shutdownSection = retrieveSections(section.second);
            QStringList shutdownList = shutdownSection.getNode().split("-");
            emit sectionOff(shutdownList[0].toInt(),shutdownList[1].toInt());
        }
    }
}

//void TrainMonitor::crossoverMonitor(Section sec, engineSection es)
//{

//}

Section TrainMonitor::retrieveSections(QString section)
{
	Section newSection;
	//int NotFoundIndex;

	bool found = false;
	for (Section it : m_sectionList)
	{
		if (it.getNode() == section)
		{
			newSection = it;
			found = true;
			break;
		}
	}

	if (!found)
	{
		qWarning("Invalid section:%s. Are you sure the section exists?", section.toLatin1().constData());
	}

	return newSection;
}

void TrainMonitor::generateSectionList()
{
#pragma message("[MKJ] Do we want to move this to a central location?")
	qDebug() << "Testing file input";
	QString filename = QDir::currentPath().append("/Sections.txt");
	QFile infile(filename);
	if (!infile.open(QIODevice::ReadOnly | QIODevice::Text)) {

		qFatal("Cannot find input file: %s", filename.toLatin1().constData());
		return;
	}

	QTextStream in(&infile);
	QString node;
	int numOfConns;
    QString conn1, conn2, conn3;
    int ltNum; bool thrownLeft;

	while (!in.atEnd())
	{

		QStringList splitString = in.readLine().split(",");
        node = splitString[0];
        qDebug() << "node:" << node;
        numOfConns = splitString[1].toInt();
        conn1 = splitString[2];
        conn2 = splitString[3];
        conn3 = splitString[4];
        ltNum = splitString[5].toInt();
        thrownLeft = (splitString[6] == "false")? false : true;

        Section sec = Section(node, numOfConns, conn1, conn2,
            conn3, ltNum, thrownLeft);
        QStringList shutdownList = node.split("-");
        sec.setBoardNum(shutdownList[0].toInt());
        sec.setSection(shutdownList[1].toInt());
        qDebug() << "TRACK SECTION:" << QString::number(sec.getBoardNum()) << "-" << QString::number(sec.getSection()) << " CONN1:" << conn1 << ", CONN2:" << conn2;

		m_sectionList.append(sec);
	}
	infile.close();
}

void TrainMonitor::handle_serialOpened()
{
    int switches = 0;
    for (Section  sec : m_sectionList)
    {
        if (sec.getNumOfConns() ==  3)
        {
            switches++;
            emit throwTurnout(sec.getLtNum());
            emit sectionOff(sec.getBoardNum(),sec.getSection());
            QThread::msleep(250);
        }
    }

    qDebug() << switches << " switches have be initialized";
    emit printSectionsOn();
}

Section TrainMonitor::findNextSection(Section previousSection,
	Section currentSection)
{
	Section nextSection;
	Section temp;

	if (previousSection.getNode() != "" && currentSection.getNode() != "")
	{
		switch (currentSection.getNumOfConns())
		{
		case 1:
		{
			// The next section will be a null string
			break;
		}
		case 2:
		case 4:
		{
			// The next section will be the only other choice other
			// than the previous section (straight section) or conn1
			// or conn2 (crossover)
			if (currentSection.getConn1() == previousSection.getNode())
			{
				nextSection = retrieveSections(
					currentSection.getConn2());
			}
			else
			{
				nextSection = retrieveSections(
					currentSection.getConn1());
			}
			break;
		}
		case 3:
		{
			if (currentSection.getConn1() == previousSection.getNode())
			{
                if (currentSection.getThrownLeft())	// configured left
				{
					nextSection = retrieveSections(
						currentSection.getConn2());
				}
				else
				{
					nextSection = retrieveSections(
						currentSection.getConn3());
				}
			}
			else
			{
				nextSection = retrieveSections(
					currentSection.getConn1());
			}
		}
		}
	}
	else
	{
		// One or both of the track sections are null. Therefore, the next
		// section will be null too
	}

	return nextSection;
}

/// Updates to an endpoint.....fix comment later
void TrainMonitor::updateSingleConnList(Section current)
{
    bool found = false;
    for(auto sec : sectionPairs)
    {
        if (sec.second == current.getConn1())
        {
            sec.first = sec.second;
            sec.second = current.getNode();
            found = true;
        }
    }

    if(!found)
    {
        qDebug() << "Section " << current.getNode() << " not found, adding to list" << endl;
        /// TODO
        std::pair<QString, QString> secPair=
                std::make_pair<QString, QString>("", current.getNode());
        sectionPairs.push_back(secPair);
    }
}

/// Updates strait aways.....
void TrainMonitor::updateDoubleConnList(Section current)
{
    bool found = false;
    for(auto sec : sectionPairs)
    {
        if (sec.second == current.getConn1() ||
                sec.second == current.getConn2())
        {
            sec.first = sec.second;
            sec.second = current.getNode();
            found = true;
        }
    }

    if(!found)
    {
        qDebug() << "Section " << current.getNode() << " not found, adding to list" << endl;
        /// TODO
        std::pair<QString, QString> secPair=
                std::make_pair<QString, QString>("", current.getNode());
        sectionPairs.push_back(secPair);
    }
}

/// Updates switches.....
void TrainMonitor::updateTripleConnList(Section current)
{
    bool found = false;
    for(auto sec : sectionPairs)
    {
        if (sec.second == current.getConn1() ||
                sec.second == current.getConn2() ||
                sec.second == current.getConn3())
        {
            sec.first = sec.second;
            sec.second = current.getNode();
            found = true;
        }
    }

    if(!found)
        if(!found)
        {
            qDebug() << "Section " << current.getNode() << " not found, adding to list" << endl;
            /// TODO
            std::pair<QString, QString> secPair =
                     std::make_pair<QString, QString>("", current.getNode());
            sectionPairs.push_back(secPair);
        }
}

/// Updates Crossovers....
void TrainMonitor::updateQuadConnList(Section current)
{
    // TODO
}

QString TrainMonitor::getNextStraightSection(Section previous, Section current)
{
    QString nextSection;
    if(previous.getNode() == current.getConn1())
    {
        nextSection = current.getConn2();
    }
    else
    {
        nextSection = current.getConn1();
    }

    return nextSection;
}

QString TrainMonitor::getNextSwitchSection(Section previous, Section current)
{
    QString nextSection;

    if(previous.getNode() == current.getConn2() ||
            previous.getNode() == current.getConn3())
    {
        nextSection = current.getConn1();
    }
    else
    {
        if(!current.getThrownLeft())
        {
            if(current.getThrown())
            {
                nextSection = current.getConn3();
            }
            else
            {
                nextSection = current.getConn2();
            }
        }
        else
        {
            if(current.getThrown())
            {
                nextSection = current.getConn2();
            }
            else
            {
                nextSection = current.getConn3();
            }
        }
    }

    return nextSection;
}

void TrainMonitor::do_handleSwitch(int LT, bool closed)
{
    qDebug() << "do_handleSwitch() entered";

    for(auto section : m_sectionList)
    {
        if(section.getLtNum() == LT)
        {
            if(closed)
            {
                section.setThrown(false);
            }
            else
            {
                section.setThrown(true);
            }
        }
    }
}
<commit_msg>changed the not found qDebug printout<commit_after>#include "trainmonitor.h"
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QThread>

TrainMonitor::TrainMonitor()
{
#pragma message("[MKJ] Clean up when everything is done")
#pragma message("[MKJ] Look for things that would be useful in a log")

}

TrainMonitor::~TrainMonitor()
{

}

void TrainMonitor::do_run() {
	generateSectionList();
}

void TrainMonitor::do_handleOccupancy(QString section, bool state)
{
    qDebug() << "do_handleOccupancy entered";
	qDebug() << "New Occupancy Data at Monitor:" << section << " State:" << state;
	Section monitoredSection = retrieveSections(section);
	monitoredSection.setOccupancy(state);
    //if (state) Monitor(monitoredSection);
    if (state) Monitor(section);
}

void TrainMonitor::Monitor(QString section)
{
    qDebug() << endl << endl;

    for (auto section : sectionPairs)
    {
        qDebug() << "last section is: " << section.first << " current section is:" << section.second << endl;
    }

    qDebug() << endl << endl;
#pragma message("[MKJ] Will nextSection1 be enough padding for a crash scenario?")
        //Section monitorSection = es.path.getNextSection1();

    Section currentSection = retrieveSections(section);
    qDebug() << "Starting monitor ....." << endl;
    switch (currentSection.getNumOfConns())
    {
        case 1:		// Endpoint case
        {
            updateSingleConnList(currentSection);
            qDebug() << "entered endpoint monitor" << endl;
            endpointMonitor(currentSection);
            break;
        }
        case 2:		// Straight case
        {
            updateDoubleConnList(currentSection);
            qDebug() << "entered straight monitor" << endl;
            straightMonitor(currentSection);
            break;
        }
        case 3:		// Switch case
        {
            updateTripleConnList(currentSection);
            qDebug() << "entered switch monitor" << endl;
            switchMonitor(currentSection);
            break;
        }
        case 4:		// Crossover case
        {
            updateQuadConnList(currentSection);
            qDebug() << "entered crossover monitor" << endl;
            //crossoverMonitor(currentSection);
            break;
        }
        default:
        {
            qFatal("Invalid track type");
            break;
        }
    }
}

void TrainMonitor::endpointMonitor(Section sec)
{
	// Shutdown the section since the means the train is headed
    // towards the end of the track
    for (auto section : sectionPairs)
    {
        if (sec.getNode() == section.second)
        {
            if(section.first != "")
            {
                qDebug() << "Shutting off section " << section.second;
                Section shutdownSection = retrieveSections(section.second);
                QStringList shutdownList = shutdownSection.getNode().split("-");
                emit sectionOff(shutdownList[0].toInt(),shutdownList[1].toInt());
            }
        }
    }
}

void TrainMonitor::straightMonitor(Section sec)
{
    QString nextSection;
    bool found = false;

    for (auto section : sectionPairs)
    {

        qDebug() << sec.getNode() << " sec.second is:" << section.second << endl;
        if(sec.getNode() == section.second)
        {
            nextSection = getNextStraightSection(
                        retrieveSections(section.first), retrieveSections(section.second));
            found = true;
        }
    }

   /* if(!found)
    {
        qDebug() << "Shit didn't work homie!!!";
    }*/

    for(auto section : sectionPairs)
    {
        if(nextSection == section.second)
        {
            //emit trackOff();
            qDebug() << "Shutting off section " << section.second;
            Section shutdownSection = retrieveSections(section.second);
            emit sectionOff(shutdownSection.getBoardNum(),shutdownSection.getSection());
        }
    }
}

void TrainMonitor::switchMonitor(Section sec)
{
    QString monitorSection;
    QString nextSection;
    for (auto section : sectionPairs)
    {
        if(sec.getNode() == section.second)
        {
            nextSection = getNextStraightSection(
                        retrieveSections(section.first), retrieveSections(section.second));
        }

        if(nextSection != "")
        {
            switch (retrieveSections(nextSection).getNumOfConns())
            {
                case 1: {
                    //emit trackOff();
                    qDebug() << "Shutting off section " << section.second;
                    Section shutdownSection = retrieveSections(nextSection);
                    QStringList shutdownList = shutdownSection.getNode().split("-");
                    emit sectionOff(shutdownList[0].toInt(),shutdownList[1].toInt());

                    break;
                } case 2: {
                    monitorSection = getNextStraightSection(
                                retrieveSections(section.first), retrieveSections(nextSection));
                    break;
                } case 3: {
                    monitorSection = getNextStraightSection(
                                retrieveSections(section.second), retrieveSections(nextSection));
                    break;
                } case 4:
                    // TODO
                    break;
            }
        }
    }

    for (auto section : sectionPairs)
    {
        if(section.second == monitorSection)
        {
            //emit trackOff();
            qDebug() << "Shutting off section " << section.second;
            Section shutdownSection = retrieveSections(section.second);
            QStringList shutdownList = shutdownSection.getNode().split("-");
            emit sectionOff(shutdownList[0].toInt(),shutdownList[1].toInt());
        }
    }
}

//void TrainMonitor::crossoverMonitor(Section sec, engineSection es)
//{

//}

Section TrainMonitor::retrieveSections(QString section)
{
	Section newSection;
	//int NotFoundIndex;

	bool found = false;
	for (Section it : m_sectionList)
	{
		if (it.getNode() == section)
		{
			newSection = it;
			found = true;
			break;
		}
	}

	if (!found)
	{
        qDebug() << "Invalid section:" << section << ", Are you sure the section exists?" << section;
	}

	return newSection;
}

void TrainMonitor::generateSectionList()
{
#pragma message("[MKJ] Do we want to move this to a central location?")
	qDebug() << "Testing file input";
	QString filename = QDir::currentPath().append("/Sections.txt");
	QFile infile(filename);
	if (!infile.open(QIODevice::ReadOnly | QIODevice::Text)) {

		qFatal("Cannot find input file: %s", filename.toLatin1().constData());
		return;
	}

	QTextStream in(&infile);
	QString node;
	int numOfConns;
    QString conn1, conn2, conn3;
    int ltNum; bool thrownLeft;

	while (!in.atEnd())
	{

		QStringList splitString = in.readLine().split(",");
        node = splitString[0];
        qDebug() << "node:" << node;
        numOfConns = splitString[1].toInt();
        conn1 = splitString[2];
        conn2 = splitString[3];
        conn3 = splitString[4];
        ltNum = splitString[5].toInt();
        thrownLeft = (splitString[6] == "false")? false : true;

        Section sec = Section(node, numOfConns, conn1, conn2,
            conn3, ltNum, thrownLeft);
        QStringList shutdownList = node.split("-");
        sec.setBoardNum(shutdownList[0].toInt());
        sec.setSection(shutdownList[1].toInt());
        qDebug() << "TRACK SECTION:" << QString::number(sec.getBoardNum()) << "-" << QString::number(sec.getSection()) << " CONN1:" << conn1 << ", CONN2:" << conn2;

		m_sectionList.append(sec);
	}
	infile.close();
}

void TrainMonitor::handle_serialOpened()
{
    int switches = 0;
    for (Section  sec : m_sectionList)
    {
        if (sec.getNumOfConns() ==  3)
        {
            switches++;
            emit throwTurnout(sec.getLtNum());
            emit sectionOff(sec.getBoardNum(),sec.getSection());
            QThread::msleep(250);
        }
    }

    qDebug() << switches << " switches have be initialized";
    emit printSectionsOn();
}

Section TrainMonitor::findNextSection(Section previousSection,
	Section currentSection)
{
	Section nextSection;
	Section temp;

	if (previousSection.getNode() != "" && currentSection.getNode() != "")
	{
		switch (currentSection.getNumOfConns())
		{
		case 1:
		{
			// The next section will be a null string
			break;
		}
		case 2:
		case 4:
		{
			// The next section will be the only other choice other
			// than the previous section (straight section) or conn1
			// or conn2 (crossover)
			if (currentSection.getConn1() == previousSection.getNode())
			{
				nextSection = retrieveSections(
					currentSection.getConn2());
			}
			else
			{
				nextSection = retrieveSections(
					currentSection.getConn1());
			}
			break;
		}
		case 3:
		{
			if (currentSection.getConn1() == previousSection.getNode())
			{
                if (currentSection.getThrownLeft())	// configured left
				{
					nextSection = retrieveSections(
						currentSection.getConn2());
				}
				else
				{
					nextSection = retrieveSections(
						currentSection.getConn3());
				}
			}
			else
			{
				nextSection = retrieveSections(
					currentSection.getConn1());
			}
		}
		}
	}
	else
	{
		// One or both of the track sections are null. Therefore, the next
		// section will be null too
	}

	return nextSection;
}

/// Updates to an endpoint.....fix comment later
void TrainMonitor::updateSingleConnList(Section current)
{
    bool found = false;
    for(auto sec : sectionPairs)
    {
        if (sec.second == current.getConn1())
        {
            sec.first = sec.second;
            sec.second = current.getNode();
            found = true;
        }
    }

    if(!found)
    {
        qDebug() << "Section " << current.getNode() << " not found, adding to list" << endl;
        /// TODO
        std::pair<QString, QString> secPair=
                std::make_pair<QString, QString>("", current.getNode());
        sectionPairs.push_back(secPair);
    }
}

/// Updates strait aways.....
void TrainMonitor::updateDoubleConnList(Section current)
{
    bool found = false;
    for(auto sec : sectionPairs)
    {
        if (sec.second == current.getConn1() ||
                sec.second == current.getConn2())
        {
            sec.first = sec.second;
            sec.second = current.getNode();
            found = true;
        }
    }

    if(!found)
    {
        qDebug() << "Section " << current.getNode() << " not found, adding to list" << endl;
        /// TODO
        std::pair<QString, QString> secPair=
                std::make_pair<QString, QString>("", current.getNode());
        sectionPairs.push_back(secPair);
    }
}

/// Updates switches.....
void TrainMonitor::updateTripleConnList(Section current)
{
    bool found = false;
    for(auto sec : sectionPairs)
    {
        if (sec.second == current.getConn1() ||
                sec.second == current.getConn2() ||
                sec.second == current.getConn3())
        {
            sec.first = sec.second;
            sec.second = current.getNode();
            found = true;
        }
    }

    if(!found)
        if(!found)
        {
            qDebug() << "Section " << current.getNode() << " not found, adding to list" << endl;
            /// TODO
            std::pair<QString, QString> secPair =
                     std::make_pair<QString, QString>("", current.getNode());
            sectionPairs.push_back(secPair);
        }
}

/// Updates Crossovers....
void TrainMonitor::updateQuadConnList(Section current)
{
    // TODO
}

QString TrainMonitor::getNextStraightSection(Section previous, Section current)
{
    QString nextSection;
    if(previous.getNode() == current.getConn1())
    {
        nextSection = current.getConn2();
    }
    else
    {
        nextSection = current.getConn1();
    }

    return nextSection;
}

QString TrainMonitor::getNextSwitchSection(Section previous, Section current)
{
    QString nextSection;

    if(previous.getNode() == current.getConn2() ||
            previous.getNode() == current.getConn3())
    {
        nextSection = current.getConn1();
    }
    else
    {
        if(!current.getThrownLeft())
        {
            if(current.getThrown())
            {
                nextSection = current.getConn3();
            }
            else
            {
                nextSection = current.getConn2();
            }
        }
        else
        {
            if(current.getThrown())
            {
                nextSection = current.getConn2();
            }
            else
            {
                nextSection = current.getConn3();
            }
        }
    }

    return nextSection;
}

void TrainMonitor::do_handleSwitch(int LT, bool closed)
{
    qDebug() << "do_handleSwitch() entered";

    for(auto section : m_sectionList)
    {
        if(section.getLtNum() == LT)
        {
            if(closed)
            {
                section.setThrown(false);
            }
            else
            {
                section.setThrown(true);
            }
        }
    }
}
<|endoftext|>


<commit_before>#include <eeros/control/Constant.hpp>
#include <eeros/math/Matrix.hpp>
#include <eeros/core/Fault.hpp>
#include <eeros/control/Transition.hpp>
#include <gtest/gtest.h>
#include <Utils.hpp>

using namespace eeros;
using namespace eeros::control;
using namespace eeros::math;

TEST(controlTransitionNameTest, naming) {
	Transition<> t1(1);
	EXPECT_EQ(t1.inBlock.getName(), std::string(""));
	t1.inBlock.setName("transition block up");
	EXPECT_EQ(t1.inBlock.getName(), std::string("transition block up"));
	Transition<> t2(1);
	EXPECT_EQ(t2.inBlock.getName(), std::string(""));
	t2.inBlock.setName("transition block down");
	EXPECT_EQ(t2.inBlock.getName(), std::string("transition block down"));
}

TEST(controlTransitionNanTest, nan) {
	Transition<> t1(1);
	t1.inBlock.setName("t1");
	EXPECT_TRUE(std::isnan(t1.outBlock.getOut().getSignal().getValue()));
	Transition<> t2(1);
	t2.inBlock.setName("t2");
	EXPECT_TRUE(std::isnan(t2.outBlock.getOut().getSignal().getValue()));
	try {
		t1.inBlock.run();
		FAIL();
	} catch(eeros::Fault const & err) {
		EXPECT_EQ(err.what(), std::string("Read from an unconnected input in block 't1'"));
	}
	try {
		t2.inBlock.run();
		FAIL();
	} catch(eeros::Fault const & err) {
		EXPECT_EQ(err.what(), std::string("Read from an unconnected input in block 't2'"));
	}
}

TEST(controlTransitionSimpleTest, simple) {
	Transition<> t1(5);
	Transition<> t2(1/5);
	Constant<> c1(0), c2(0);
	t1.inBlock.getIn().connect(c1.getOut());
	t2.inBlock.getIn().connect(t1.outBlock.getOut());
	t2.outBlock.getIn().connect(c2.getOut());
	c1.run();
	timestamp_t start = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	usleep(10000);
	c2.run();	// fix the timestamp
	usleep(10000);
	c1.setValue(1.0);
	c1.run();
	timestamp_t end = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	t1.outBlock.run();
	for (int i = 0; i < 5; i++) {
		EXPECT_EQ(t1.outBlock.getOut().getSignal().getTimestamp(), start + i * (end - start) / 5);
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue(), i * 0.2, 0.001));
		t1.outBlock.run();
		t2.inBlock.run();
	}
	t2.outBlock.run();
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue(), 0.4, 0.001));
}

TEST(controlTransitionSimpleTest, vector) {
	Transition<Vector2> t1(5);
	Transition<Vector2> t2(1/5);
	Constant<Vector2> c1({0,0}), c2({0,0});
	t1.inBlock.getIn().connect(c1.getOut());
	t2.inBlock.getIn().connect(t1.outBlock.getOut());
	t2.outBlock.getIn().connect(c2.getOut());
	c1.run();
	timestamp_t start = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	usleep(10000);
	c2.run();	// fix the timestamp
	usleep(10000);
	c1.setValue({1.0, 2.0});
	c1.run();
	timestamp_t end = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	t1.outBlock.run();
	EXPECT_EQ(t1.outBlock.getOut().getSignal().getValue()[0], 0);
	for (int i = 0; i < 5; i++) {
		EXPECT_EQ(t1.outBlock.getOut().getSignal().getTimestamp(), start + i * (end - start) / 5);
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue()[0], i * 0.2, 0.001));
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue()[1], i * 0.4, 0.001));
		t1.outBlock.run();
		t2.inBlock.run();
	}
	t2.outBlock.run();
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue()[0], 0.4, 0.001));
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue()[1], 0.8, 0.001));
}

TEST(controlTransitionSimpleTest, steady) {
	Transition<> t1(5, true);
	Transition<> t2(1/5, true);
	Constant<> c1(0), c2(0);
	t1.inBlock.getIn().connect(c1.getOut());
	t2.inBlock.getIn().connect(t1.outBlock.getOut());
	t2.outBlock.getIn().connect(c2.getOut());
	c1.run();
//	timestamp_t start = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	usleep(5000);
	c1.setValue(1.0);
	c1.run();
	timestamp_t end = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	t1.outBlock.run();
	for (int i = 0; i < 5; i++) {
		EXPECT_EQ(t1.outBlock.getOut().getSignal().getTimestamp(), end);
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue(), 1.0, 1e-10));
		t1.outBlock.run();
		t2.inBlock.run();
	}
	t2.outBlock.run();
	EXPECT_EQ(t2.outBlock.getOut().getSignal().getTimestamp(), end);
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue(), 1.0, 1e-10));
}

<commit_msg>Flex restrictions on timestamps<commit_after>#include <eeros/control/Constant.hpp>
#include <eeros/math/Matrix.hpp>
#include <eeros/core/Fault.hpp>
#include <eeros/control/Transition.hpp>
#include <gtest/gtest.h>
#include <Utils.hpp>

using namespace eeros;
using namespace eeros::control;
using namespace eeros::math;

TEST(controlTransitionNameTest, naming) {
	Transition<> t1(1);
	EXPECT_EQ(t1.inBlock.getName(), std::string(""));
	t1.inBlock.setName("transition block up");
	EXPECT_EQ(t1.inBlock.getName(), std::string("transition block up"));
	Transition<> t2(1);
	EXPECT_EQ(t2.inBlock.getName(), std::string(""));
	t2.inBlock.setName("transition block down");
	EXPECT_EQ(t2.inBlock.getName(), std::string("transition block down"));
}

TEST(controlTransitionNanTest, nan) {
	Transition<> t1(1);
	t1.inBlock.setName("t1");
	EXPECT_TRUE(std::isnan(t1.outBlock.getOut().getSignal().getValue()));
	Transition<> t2(1);
	t2.inBlock.setName("t2");
	EXPECT_TRUE(std::isnan(t2.outBlock.getOut().getSignal().getValue()));
	try {
		t1.inBlock.run();
		FAIL();
	} catch(eeros::Fault const & err) {
		EXPECT_EQ(err.what(), std::string("Read from an unconnected input in block 't1'"));
	}
	try {
		t2.inBlock.run();
		FAIL();
	} catch(eeros::Fault const & err) {
		EXPECT_EQ(err.what(), std::string("Read from an unconnected input in block 't2'"));
	}
}

TEST(controlTransitionSimpleTest, simple) {
	Transition<> t1(5);
	Transition<> t2(1/5);
	Constant<> c1(0), c2(0);
	t1.inBlock.getIn().connect(c1.getOut());
	t2.inBlock.getIn().connect(t1.outBlock.getOut());
	t2.outBlock.getIn().connect(c2.getOut());
	c1.run();
	timestamp_t start = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	usleep(10000);
	c2.run();	// fix the timestamp
	usleep(10000);
	c1.setValue(1.0);
	c1.run();
	timestamp_t end = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	t1.outBlock.run();
	for (int i = 0; i < 5; i++) {
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getTimestamp(), start + i * (end - start) / 5, 20));
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue(), i * 0.2, 0.001));
		t1.outBlock.run();
		t2.inBlock.run();
	}
	t2.outBlock.run();
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue(), 0.4, 0.001));
}

TEST(controlTransitionSimpleTest, vector) {
	Transition<Vector2> t1(5);
	Transition<Vector2> t2(1/5);
	Constant<Vector2> c1({0,0}), c2({0,0});
	t1.inBlock.getIn().connect(c1.getOut());
	t2.inBlock.getIn().connect(t1.outBlock.getOut());
	t2.outBlock.getIn().connect(c2.getOut());
	c1.run();
	timestamp_t start = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	usleep(10000);
	c2.run();	// fix the timestamp
	usleep(10000);
	c1.setValue({1.0, 2.0});
	c1.run();
	timestamp_t end = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	t1.outBlock.run();
	EXPECT_EQ(t1.outBlock.getOut().getSignal().getValue()[0], 0);
	for (int i = 0; i < 5; i++) {
		EXPECT_TRUE(t1.outBlock.getOut().getSignal().getTimestamp(), start + i * (end - start) / 5, 20));
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue()[0], i * 0.2, 0.001));
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue()[1], i * 0.4, 0.001));
		t1.outBlock.run();
		t2.inBlock.run();
	}
	t2.outBlock.run();
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue()[0], 0.4, 0.001));
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue()[1], 0.8, 0.001));
}

TEST(controlTransitionSimpleTest, steady) {
	Transition<> t1(5, true);
	Transition<> t2(1/5, true);
	Constant<> c1(0), c2(0);
	t1.inBlock.getIn().connect(c1.getOut());
	t2.inBlock.getIn().connect(t1.outBlock.getOut());
	t2.outBlock.getIn().connect(c2.getOut());
	c1.run();
//	timestamp_t start = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	usleep(5000);
	c1.setValue(1.0);
	c1.run();
	timestamp_t end = c1.getOut().getSignal().getTimestamp();
	t1.inBlock.run();
	t1.outBlock.run();
	for (int i = 0; i < 5; i++) {
		EXPECT_EQ(t1.outBlock.getOut().getSignal().getTimestamp(), end);
		EXPECT_TRUE(Utils::compareApprox(t1.outBlock.getOut().getSignal().getValue(), 1.0, 1e-10));
		t1.outBlock.run();
		t2.inBlock.run();
	}
	t2.outBlock.run();
	EXPECT_EQ(t2.outBlock.getOut().getSignal().getTimestamp(), end);
	EXPECT_TRUE(Utils::compareApprox(t2.outBlock.getOut().getSignal().getValue(), 1.0, 1e-10));
}

<|endoftext|>


<commit_before>//
// ulib - a collection of useful classes
// Copyright (C) 2006,2007,2008,2014,2017 Michael Fink
//
/// \file TextStreamFilter.cpp text stream filter
//
#include "stdafx.h"
#include <ulib/stream/TextStreamFilter.hpp>
#include <ulib/Exception.hpp>
#include <ulib/UTF8.hpp>
#include <vector>

/// character for carriage return
const TCHAR c_cCR = _T('\r');

/// character for line feed
const TCHAR c_cLF = _T('\n');

using Stream::TextStreamFilter;

TextStreamFilter::TextStreamFilter(Stream::IStream& stream,
   ETextEncoding textEncoding,
   ELineEndingMode lineEndingMode)
   :ITextStream(textEncoding, lineEndingMode),
   m_stream(stream),
   m_isCharPutBack(false),
   m_putBackChar(0)
{
   if (textEncoding == textEncodingNative)
#if defined(_UNICODE) || defined(UNICODE)
      m_textEncoding = textEncodingUCS2;
#else
      m_textEncoding = textEncodingAnsi;
#endif

   if (lineEndingMode == lineEndingNative)
#ifdef _WIN32
      m_lineEndingMode = lineEndingCRLF;
#elif defined(__ANDROID__)
      m_lineEndingMode = lineEndingLF;
#else
#  error define proper line ending mode for this platform!
#endif
}

TCHAR TextStreamFilter::ReadChar()
{
   if (m_isCharPutBack)
   {
      m_isCharPutBack = false;
      return m_putBackChar;
   }

   TCHAR ch = 0;

   // depending on the text encoding type, read next byte
   switch (m_textEncoding)
   {
   case textEncodingNative:
      // note: textEncodingNative should have been set to the appropriate encoding in ctor!
      ATLASSERT(false);
      break;

   case textEncodingAnsi:
   {
      char chAnsi = m_stream.ReadByte();

      // use CString convert
      CString cszCh(chAnsi);
      ch = cszCh.GetAt(0);
   }
   break;

   case textEncodingUTF8:
   {
      // read first octet; determines how much further octets are needed; all
      // remaining octets start with bit 7 set and bit 6 cleared (10xx xxxx)
      BYTE bLeading = m_stream.ReadByte();
      if (bLeading <= 0x7f)
      {
         // easy case: char in ASCII zone
         ch = static_cast<char>(bLeading);
         break;
      }

      // count bits from bit 7 until a 0 occurs
      unsigned int uiCount = 0;
      while ((bLeading & 0x80) != 0)
         uiCount++, bLeading <<= 1;

      // only one bit? or more than 6? illegal value for leading octet!
      if (uiCount <= 1 || uiCount > 6)
         throw Exception(_T("illegal utf8 lead byte encountered"), __FILE__, __LINE__);

      // move remaining bits in position
      bLeading >>= uiCount;

      // move remaining bits to bits 6..n, so that the next byte's 6 bits
      // can fill out the dword
      DWORD dwBits = bLeading;

      // read in remaining bytes, remove bits 6 and 7 and add it to the resulting byte
      for (unsigned int ui = 1; ui < uiCount; ui++)
      {
         BYTE bNext = m_stream.ReadByte();
         if ((bNext & 0xc0) != 0x80)
            throw Exception(_T("illegal utf8 byte encountered"), __FILE__, __LINE__);
         dwBits <<= 6;
         dwBits |= bNext & 0x3f;
      }

      if (dwBits > 0xffff)
         throw Exception(_T("utf8 character out of range"), __FILE__, __LINE__);

#if defined(_UNICODE) || defined(UNICODE)
      ch = static_cast<TCHAR>(dwBits & 0xffff);
#else
      WCHAR chw = static_cast<WCHAR>(dwBits & 0xffff);

      CStringA ansiChar(chw);
      ch = ansiChar.GetAt(0);
#endif
   }
   break;

   case textEncodingUCS2:
      // assume UCS2-LE
      ch = m_stream.ReadByte();
      ch |= static_cast<TCHAR>(m_stream.ReadByte()) << 8;
      break;

   default:
      ATLASSERT(false);
      break;
   }

   return ch;
}

void TextStreamFilter::ReadLine(CString& line)
{
   line.Empty();

   TCHAR lastCharacter = 0;
#ifdef _WIN32_WCE
   ULONGLONG position = 0UL;
#else
   ULONGLONG position = 0ULL;
#endif

   // depending on the line type, read in a line of characters
   for (; !m_stream.AtEndOfStream();)
   {
      TCHAR ch = ReadChar();

      // carriage return: can be CRLF, CR, and "any"
      if (ch == c_cCR)
      {
         if (m_lineEndingMode == lineEndingCR)
            break; // found CR; in ReadAny mode a LF might follow

         if (m_lineEndingMode == lineEndingReadAny)
         {
            // found CR; a a LF might follow; read more chars
            lastCharacter = ch;
            position = m_stream.Position();
            continue;
         }

         if (m_lineEndingMode == lineEndingCRLF)
         {
            // check if at end of stream
            if (m_stream.AtEndOfStream())
               break;

            // threre might be a LF, but we don't know for sure, so check
            TCHAR nextCh = ReadChar();
            if (c_cLF == nextCh)
               break; // recognized CRLF

            // some other char, just do normal processing by appending CR, and
            // putting back character
            PutBackChar(nextCh);
         }
      }
      else
         // line feed: can be LF, and the LF part in CRLF when in "any" mode
         if (ch == c_cLF)
         {
            if (m_lineEndingMode == lineEndingLF)
               break; // found LF

            // in any mode, the last character must be a CR to start a new line
            if (m_lineEndingMode == lineEndingReadAny)
            {
               // last character may have been a CR, so we got CRLF
               // or it was another character, then we simply got LF
               break;
            }
         }
         else
            // not CR nor LF, but previous was a CR
            if (m_lineEndingMode == lineEndingReadAny && lastCharacter == c_cCR)
            {
               // recognized a CR line ending; try to put back current
               if (m_stream.CanSeek())
               {
                  // seek back to previous position
                  m_stream.Seek(position, Stream::IStream::seekBegin);
               }
               else
               {
                  // can't seek, so put back character
                  PutBackChar(ch);
               }
               break; // line is finished
            }

      line += ch;

      if (m_lineEndingMode == lineEndingReadAny)
         lastCharacter = ch;
   }
}

void TextStreamFilter::Write(const CString& text)
{
   // write text in proper encoding
   DWORD numWriteBytes = 0;

   switch (m_textEncoding)
   {
   case textEncodingAnsi:
   {
      CStringA ansiText = text;
      LPCSTR textPtr = ansiText;
      m_stream.Write(textPtr, static_cast<DWORD>(strlen(textPtr) * sizeof(*textPtr)), numWriteBytes);
   }
   break;

   case textEncodingUTF8:
   {
      std::vector<char> buffer;
      StringToUTF8(text, buffer);

      // don't write null byte at the end
      m_stream.Write(buffer.data(), static_cast<DWORD>(buffer.size() - 1), numWriteBytes);
   }
   break;

   case textEncodingUCS2:
   {
      CStringW unicodeText = text;
      LPCWSTR textPtr = unicodeText;
      m_stream.Write(textPtr, static_cast<DWORD>(wcslen(textPtr) * sizeof(*textPtr)), numWriteBytes);
   }
   break;

   default:
      ATLASSERT(false);
      break;
   }
}

void TextStreamFilter::WriteEndline()
{
   ATLASSERT(m_lineEndingMode != lineEndingReadAny);

   switch (m_lineEndingMode)
   {
   case lineEndingCRLF: Write(_T("\r\n")); break;
   case lineEndingLF:   Write(_T("\n")); break;
   case lineEndingCR:   Write(_T("\r")); break;

   default:
      ATLASSERT(false);
      break;
   }
}

void TextStreamFilter::PutBackChar(TCHAR ch)
{
   ATLASSERT(false == m_isCharPutBack);

   m_putBackChar = ch;
   m_isCharPutBack = true;
}
<commit_msg>fixed SonarQube bug<commit_after>//
// ulib - a collection of useful classes
// Copyright (C) 2006,2007,2008,2014,2017 Michael Fink
//
/// \file TextStreamFilter.cpp text stream filter
//
#include "stdafx.h"
#include <ulib/stream/TextStreamFilter.hpp>
#include <ulib/Exception.hpp>
#include <ulib/UTF8.hpp>
#include <vector>

/// character for carriage return
const TCHAR c_cCR = _T('\r');

/// character for line feed
const TCHAR c_cLF = _T('\n');

using Stream::TextStreamFilter;

TextStreamFilter::TextStreamFilter(Stream::IStream& stream,
   ETextEncoding textEncoding,
   ELineEndingMode lineEndingMode)
   :ITextStream(textEncoding, lineEndingMode),
   m_stream(stream),
   m_isCharPutBack(false),
   m_putBackChar(0)
{
   if (textEncoding == textEncodingNative)
#if defined(_UNICODE) || defined(UNICODE)
      m_textEncoding = textEncodingUCS2;
#else
      m_textEncoding = textEncodingAnsi;
#endif

   if (lineEndingMode == lineEndingNative)
#ifdef _WIN32
      m_lineEndingMode = lineEndingCRLF;
#elif defined(__ANDROID__)
      m_lineEndingMode = lineEndingLF;
#else
#  error define proper line ending mode for this platform!
#endif
}

TCHAR TextStreamFilter::ReadChar()
{
   if (m_isCharPutBack)
   {
      m_isCharPutBack = false;
      return m_putBackChar;
   }

   TCHAR ch = 0;

   // depending on the text encoding type, read next byte
   switch (m_textEncoding)
   {
   case textEncodingNative:
      // note: textEncodingNative should have been set to the appropriate encoding in ctor!
      ATLASSERT(false);
      break;

   case textEncodingAnsi:
   {
      char chAnsi = m_stream.ReadByte();

      // use CString convert
      CString cszCh(chAnsi);
      ch = cszCh.GetAt(0);
   }
   break;

   case textEncodingUTF8:
   {
      // read first octet; determines how much further octets are needed; all
      // remaining octets start with bit 7 set and bit 6 cleared (10xx xxxx)
      BYTE bLeading = m_stream.ReadByte();
      if (bLeading <= 0x7f)
      {
         // easy case: char in ASCII zone
         ch = static_cast<char>(bLeading);
         break;
      }

      // count bits from bit 7 until a 0 occurs
      unsigned int uiCount = 0;
      while ((bLeading & 0x80) != 0)
         uiCount++, bLeading <<= 1;

      // only one bit? or more than 6? illegal value for leading octet!
      if (uiCount <= 1 || uiCount > 6)
         throw Exception(_T("illegal utf8 lead byte encountered"), __FILE__, __LINE__);

      // move remaining bits in position
      bLeading >>= uiCount;

      // move remaining bits to bits 6..n, so that the next byte's 6 bits
      // can fill out the dword
      DWORD dwBits = bLeading;

      // read in remaining bytes, remove bits 6 and 7 and add it to the resulting byte
      for (unsigned int ui = 1; ui < uiCount; ui++)
      {
         BYTE bNext = m_stream.ReadByte();
         if ((bNext & 0xc0) != 0x80)
            throw Exception(_T("illegal utf8 byte encountered"), __FILE__, __LINE__);
         dwBits <<= 6;
         dwBits |= bNext & 0x3f;
      }

      if (dwBits > 0xffff)
         throw Exception(_T("utf8 character out of range"), __FILE__, __LINE__);

#if defined(_UNICODE) || defined(UNICODE)
      ch = static_cast<TCHAR>(dwBits & 0xffff);
#else
      WCHAR chw = static_cast<WCHAR>(dwBits & 0xffff);

      CStringA ansiChar(chw);
      ch = ansiChar.GetAt(0);
#endif
   }
   break;

   case textEncodingUCS2:
      // assume UCS2-LE
      ch = m_stream.ReadByte();
      ch |= static_cast<TCHAR>(m_stream.ReadByte()) << 8;
      break;

   default:
      ATLASSERT(false);
      break;
   }

   return ch;
}

void TextStreamFilter::ReadLine(CString& line)
{
   line.Empty();

   TCHAR lastCharacter = 0;
#ifdef _WIN32_WCE
   ULONGLONG position = 0UL;
#else
   ULONGLONG position = 0ULL;
#endif

   // depending on the line type, read in a line of characters
   for (; !m_stream.AtEndOfStream();)
   {
      TCHAR ch = ReadChar();

      // carriage return: can be CRLF, CR, and "any"
      if (ch == c_cCR)
      {
         if (m_lineEndingMode == lineEndingCR)
            break; // found CR; in ReadAny mode a LF might follow

         if (m_lineEndingMode == lineEndingReadAny)
         {
            // found CR; a a LF might follow; read more chars
            lastCharacter = ch;
            position = m_stream.Position();
            continue;
         }

         if (m_lineEndingMode == lineEndingCRLF)
         {
            // check if at end of stream
            if (m_stream.AtEndOfStream())
               break;

            // threre might be a LF, but we don't know for sure, so check
            TCHAR nextCh = ReadChar();
            if (c_cLF == nextCh)
               break; // recognized CRLF

            // some other char, just do normal processing by appending CR, and
            // putting back character
            PutBackChar(nextCh);
         }
      }
      else
         // line feed: can be LF, and the LF part in CRLF when in "any" mode
         if (ch == c_cLF)
         {
            if (m_lineEndingMode == lineEndingLF)
               break; // found LF

            // in any mode, the last character must be a CR to start a new line
            if (m_lineEndingMode == lineEndingReadAny)
            {
               // last character may have been a CR, so we got CRLF
               // or it was another character, then we simply got LF
               break;
            }
         }
         else
            // not CR nor LF, but previous was a CR
            if (m_lineEndingMode == lineEndingReadAny && lastCharacter == c_cCR)
            {
               // recognized a CR line ending; try to put back current
               if (m_stream.CanSeek())
               {
                  // seek back to previous position
                  m_stream.Seek(position, Stream::IStream::seekBegin);
               }
               else
               {
                  // can't seek, so put back character
                  PutBackChar(ch);
               }
               break; // line is finished
            }

      line += ch;

      if (m_lineEndingMode == lineEndingReadAny)
         lastCharacter = ch;
   }
}

void TextStreamFilter::Write(const CString& text)
{
   // write text in proper encoding
   DWORD numWriteBytes = 0;

   switch (m_textEncoding)
   {
   case textEncodingAnsi:
   {
      CStringA ansiText = text;
      LPCSTR textPtr = ansiText.GetString();
      if (ansiText.GetLength() > 0 && textPtr != nullptr)
         m_stream.Write(textPtr, static_cast<DWORD>(strlen(textPtr) * sizeof(*textPtr)), numWriteBytes);
   }
   break;

   case textEncodingUTF8:
   {
      std::vector<char> buffer;
      StringToUTF8(text, buffer);

      // don't write null byte at the end
      m_stream.Write(buffer.data(), static_cast<DWORD>(buffer.size() - 1), numWriteBytes);
   }
   break;

   case textEncodingUCS2:
   {
      CStringW unicodeText = text;
      LPCWSTR textPtr = unicodeText;
      m_stream.Write(textPtr, static_cast<DWORD>(wcslen(textPtr) * sizeof(*textPtr)), numWriteBytes);
   }
   break;

   default:
      ATLASSERT(false);
      break;
   }
}

void TextStreamFilter::WriteEndline()
{
   ATLASSERT(m_lineEndingMode != lineEndingReadAny);

   switch (m_lineEndingMode)
   {
   case lineEndingCRLF: Write(_T("\r\n")); break;
   case lineEndingLF:   Write(_T("\n")); break;
   case lineEndingCR:   Write(_T("\r")); break;

   default:
      ATLASSERT(false);
      break;
   }
}

void TextStreamFilter::PutBackChar(TCHAR ch)
{
   ATLASSERT(false == m_isCharPutBack);

   m_putBackChar = ch;
   m_isCharPutBack = true;
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Project headers.
#include "commandlinehandler.h"

// appleseed.shared headers.
#include "application/application.h"
#include "application/superlogger.h"

// appleseed.foundation headers.
#include "foundation/math/vector.h"
#include "foundation/mesh/genericmeshfilereader.h"
#include "foundation/mesh/genericmeshfilewriter.h"
#include "foundation/mesh/imeshbuilder.h"
#include "foundation/mesh/imeshwalker.h"
#include "foundation/platform/compiler.h"
#include "foundation/utility/foreach.h"

// Standard headers.
#include <cstddef>
#include <deque>
#include <list>
#include <string>
#include <vector>

using namespace appleseed::convertmeshfile;
using namespace appleseed::shared;
using namespace foundation;
using namespace std;

namespace
{
    struct Face
    {
        vector<size_t>      m_vertices;
        vector<size_t>      m_vertex_normals;
        vector<size_t>      m_vertex_tex_coords;
        size_t              m_material;
    };

    struct Mesh
    {
        string              m_name;
        vector<Vector3d>    m_vertices;
        vector<Vector3d>    m_vertex_normals;
        vector<Vector2d>    m_tex_coords;
        vector<string>      m_material_slots;
        deque<Face>         m_faces;
    };

    class MeshBuilder
      : public IMeshBuilder
    {
      public:
        const list<Mesh>& get_meshes() const
        {
            return m_meshes;
        }

        virtual void begin_mesh(const char* name) OVERRIDE
        {
            m_current_mesh = Mesh();
            m_current_mesh.m_name = name;
        }

        virtual size_t push_vertex(const Vector3d& v) OVERRIDE
        {
            m_current_mesh.m_vertices.push_back(v);
            return m_current_mesh.m_vertices.size() - 1;
        }

        virtual size_t push_vertex_normal(const Vector3d& v) OVERRIDE
        {
            m_current_mesh.m_vertex_normals.push_back(v);
            return m_current_mesh.m_vertex_normals.size() - 1;
        }

        virtual size_t push_tex_coords(const Vector2d& v) OVERRIDE
        {
            m_current_mesh.m_tex_coords.push_back(v);
            return m_current_mesh.m_tex_coords.size() - 1;
        }

        virtual size_t push_material_slot(const char* name) OVERRIDE
        {
            m_current_mesh.m_material_slots.push_back(name);
            return m_current_mesh.m_material_slots.size() - 1;
        }

        virtual void begin_face(const size_t vertex_count) OVERRIDE
        {
            m_current_face = Face();
            m_current_face.m_vertices.resize(vertex_count);
            m_current_face.m_vertex_normals.resize(vertex_count);
            m_current_face.m_vertex_tex_coords.resize(vertex_count);
            m_current_face.m_material = 0;
        }

        virtual void set_face_vertices(const size_t vertices[]) OVERRIDE
        {
            for (size_t i = 0; i < m_current_face.m_vertices.size(); ++i)
                m_current_face.m_vertices[i] = vertices[i];
        }

        virtual void set_face_vertex_normals(const size_t vertex_normals[]) OVERRIDE
        {
            for (size_t i = 0; i < m_current_face.m_vertex_normals.size(); ++i)
                m_current_face.m_vertex_normals[i] = vertex_normals[i];
        }

        virtual void set_face_vertex_tex_coords(const size_t tex_coords[]) OVERRIDE
        {
            for (size_t i = 0; i < m_current_face.m_vertex_tex_coords.size(); ++i)
                m_current_face.m_vertex_tex_coords[i] = tex_coords[i];
        }

        virtual void set_face_material(const size_t material) OVERRIDE
        {
            m_current_face.m_material = material;
        }

        virtual void end_face() OVERRIDE
        {
            m_current_mesh.m_faces.push_back(m_current_face);
        }

        virtual void end_mesh() OVERRIDE
        {
            m_meshes.push_back(m_current_mesh);
        }

      private:
        list<Mesh>  m_meshes;
        Mesh        m_current_mesh;
        Face        m_current_face;
    };

    class MeshWalker
      : public IMeshWalker
    {
      public:
        explicit MeshWalker(const Mesh& mesh)
          : m_mesh(mesh)
        {
        }

        virtual const char* get_name() const OVERRIDE
        {
            return m_mesh.m_name.c_str();
        }

        virtual size_t get_vertex_count() const OVERRIDE
        {
            return m_mesh.m_vertices.size();
        }

        virtual Vector3d get_vertex(const size_t i) const OVERRIDE
        {
            return m_mesh.m_vertices[i];
        }

        virtual size_t get_vertex_normal_count() const OVERRIDE
        {
            return m_mesh.m_vertex_normals.size();
        }

        virtual Vector3d get_vertex_normal(const size_t i) const OVERRIDE
        {
            return m_mesh.m_vertex_normals[i];
        }

        virtual size_t get_tex_coords_count() const OVERRIDE
        {
            return m_mesh.m_tex_coords.size();
        }

        virtual Vector2d get_tex_coords(const size_t i) const OVERRIDE
        {
            return m_mesh.m_tex_coords[i];
        }

        virtual size_t get_material_slot_count() const OVERRIDE
        {
            return m_mesh.m_material_slots.size();
        }

        virtual const char* get_material_slot(const size_t i) const OVERRIDE
        {
            return m_mesh.m_material_slots[i].c_str();
        }

        virtual size_t get_face_count() const
        {
            return m_mesh.m_faces.size();
        }

        virtual size_t get_face_vertex_count(const size_t face_index) const
        {
            return m_mesh.m_faces[face_index].m_vertices.size();
        }

        virtual size_t get_face_vertex(const size_t face_index, const size_t vertex_index) const
        {
            return m_mesh.m_faces[face_index].m_vertices[vertex_index];
        }

        virtual size_t get_face_vertex_normal(const size_t face_index, const size_t vertex_index) const
        {
            return m_mesh.m_faces[face_index].m_vertex_normals[vertex_index];
        }

        virtual size_t get_face_tex_coords(const size_t face_index, const size_t vertex_index) const
        {
            return m_mesh.m_faces[face_index].m_vertex_tex_coords[vertex_index];
        }

        virtual size_t get_face_material(const size_t face_index) const
        {
            return m_mesh.m_faces[face_index].m_material;
        }

      private:
        const Mesh& m_mesh;
    };
}

//
// Entry point of convertmeshfile.
//

int main(int argc, const char* argv[])
{
    SuperLogger logger;

    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Retrieve the input and output file paths.
    const string& input_filepath = cl.m_filename.values()[0];
    const string& output_filepath = cl.m_filename.values()[1];

    // Read the input mesh file.
    MeshBuilder builder;
    GenericMeshFileReader reader(input_filepath.c_str());
    reader.read(builder);

    // Write the output mesh file.
    GenericMeshFileWriter writer(output_filepath.c_str());
    for (const_each<list<Mesh> > i = builder.get_meshes(); i; ++i)
    {
        const MeshWalker walker(*i);
        writer.write(walker);
    }

    return 0;
}
<commit_msg>implemented proper error handling and reporting in the convertmeshfile tool.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Project headers.
#include "commandlinehandler.h"

// appleseed.shared headers.
#include "application/application.h"
#include "application/superlogger.h"

// appleseed.foundation headers.
#include "foundation/math/vector.h"
#include "foundation/mesh/genericmeshfilereader.h"
#include "foundation/mesh/genericmeshfilewriter.h"
#include "foundation/mesh/imeshbuilder.h"
#include "foundation/mesh/imeshwalker.h"
#include "foundation/platform/compiler.h"
#include "foundation/utility/foreach.h"
#include "foundation/utility/log.h"

// Standard headers.
#include <cstddef>
#include <deque>
#include <exception>
#include <list>
#include <string>
#include <vector>

using namespace appleseed::convertmeshfile;
using namespace appleseed::shared;
using namespace foundation;
using namespace std;

namespace
{
    struct Face
    {
        vector<size_t>      m_vertices;
        vector<size_t>      m_vertex_normals;
        vector<size_t>      m_vertex_tex_coords;
        size_t              m_material;
    };

    struct Mesh
    {
        string              m_name;
        vector<Vector3d>    m_vertices;
        vector<Vector3d>    m_vertex_normals;
        vector<Vector2d>    m_tex_coords;
        vector<string>      m_material_slots;
        deque<Face>         m_faces;
    };

    class MeshBuilder
      : public IMeshBuilder
    {
      public:
        const list<Mesh>& get_meshes() const
        {
            return m_meshes;
        }

        virtual void begin_mesh(const char* name) OVERRIDE
        {
            m_current_mesh = Mesh();
            m_current_mesh.m_name = name;
        }

        virtual size_t push_vertex(const Vector3d& v) OVERRIDE
        {
            m_current_mesh.m_vertices.push_back(v);
            return m_current_mesh.m_vertices.size() - 1;
        }

        virtual size_t push_vertex_normal(const Vector3d& v) OVERRIDE
        {
            m_current_mesh.m_vertex_normals.push_back(v);
            return m_current_mesh.m_vertex_normals.size() - 1;
        }

        virtual size_t push_tex_coords(const Vector2d& v) OVERRIDE
        {
            m_current_mesh.m_tex_coords.push_back(v);
            return m_current_mesh.m_tex_coords.size() - 1;
        }

        virtual size_t push_material_slot(const char* name) OVERRIDE
        {
            m_current_mesh.m_material_slots.push_back(name);
            return m_current_mesh.m_material_slots.size() - 1;
        }

        virtual void begin_face(const size_t vertex_count) OVERRIDE
        {
            m_current_face = Face();
            m_current_face.m_vertices.resize(vertex_count);
            m_current_face.m_vertex_normals.resize(vertex_count);
            m_current_face.m_vertex_tex_coords.resize(vertex_count);
            m_current_face.m_material = 0;
        }

        virtual void set_face_vertices(const size_t vertices[]) OVERRIDE
        {
            for (size_t i = 0; i < m_current_face.m_vertices.size(); ++i)
                m_current_face.m_vertices[i] = vertices[i];
        }

        virtual void set_face_vertex_normals(const size_t vertex_normals[]) OVERRIDE
        {
            for (size_t i = 0; i < m_current_face.m_vertex_normals.size(); ++i)
                m_current_face.m_vertex_normals[i] = vertex_normals[i];
        }

        virtual void set_face_vertex_tex_coords(const size_t tex_coords[]) OVERRIDE
        {
            for (size_t i = 0; i < m_current_face.m_vertex_tex_coords.size(); ++i)
                m_current_face.m_vertex_tex_coords[i] = tex_coords[i];
        }

        virtual void set_face_material(const size_t material) OVERRIDE
        {
            m_current_face.m_material = material;
        }

        virtual void end_face() OVERRIDE
        {
            m_current_mesh.m_faces.push_back(m_current_face);
        }

        virtual void end_mesh() OVERRIDE
        {
            m_meshes.push_back(m_current_mesh);
        }

      private:
        list<Mesh>  m_meshes;
        Mesh        m_current_mesh;
        Face        m_current_face;
    };

    class MeshWalker
      : public IMeshWalker
    {
      public:
        explicit MeshWalker(const Mesh& mesh)
          : m_mesh(mesh)
        {
        }

        virtual const char* get_name() const OVERRIDE
        {
            return m_mesh.m_name.c_str();
        }

        virtual size_t get_vertex_count() const OVERRIDE
        {
            return m_mesh.m_vertices.size();
        }

        virtual Vector3d get_vertex(const size_t i) const OVERRIDE
        {
            return m_mesh.m_vertices[i];
        }

        virtual size_t get_vertex_normal_count() const OVERRIDE
        {
            return m_mesh.m_vertex_normals.size();
        }

        virtual Vector3d get_vertex_normal(const size_t i) const OVERRIDE
        {
            return m_mesh.m_vertex_normals[i];
        }

        virtual size_t get_tex_coords_count() const OVERRIDE
        {
            return m_mesh.m_tex_coords.size();
        }

        virtual Vector2d get_tex_coords(const size_t i) const OVERRIDE
        {
            return m_mesh.m_tex_coords[i];
        }

        virtual size_t get_material_slot_count() const OVERRIDE
        {
            return m_mesh.m_material_slots.size();
        }

        virtual const char* get_material_slot(const size_t i) const OVERRIDE
        {
            return m_mesh.m_material_slots[i].c_str();
        }

        virtual size_t get_face_count() const
        {
            return m_mesh.m_faces.size();
        }

        virtual size_t get_face_vertex_count(const size_t face_index) const
        {
            return m_mesh.m_faces[face_index].m_vertices.size();
        }

        virtual size_t get_face_vertex(const size_t face_index, const size_t vertex_index) const
        {
            return m_mesh.m_faces[face_index].m_vertices[vertex_index];
        }

        virtual size_t get_face_vertex_normal(const size_t face_index, const size_t vertex_index) const
        {
            return m_mesh.m_faces[face_index].m_vertex_normals[vertex_index];
        }

        virtual size_t get_face_tex_coords(const size_t face_index, const size_t vertex_index) const
        {
            return m_mesh.m_faces[face_index].m_vertex_tex_coords[vertex_index];
        }

        virtual size_t get_face_material(const size_t face_index) const
        {
            return m_mesh.m_faces[face_index].m_material;
        }

      private:
        const Mesh& m_mesh;
    };
}

//
// Entry point of convertmeshfile.
//

int main(int argc, const char* argv[])
{
    SuperLogger logger;

    Application::check_installation(logger);

    CommandLineHandler cl;
    cl.parse(argc, argv, logger);

    // Retrieve the input and output file paths.
    const string& input_filepath = cl.m_filename.values()[0];
    const string& output_filepath = cl.m_filename.values()[1];

    // Read the input mesh file.
    MeshBuilder builder;
    try
    {
        GenericMeshFileReader reader(input_filepath.c_str());
        reader.read(builder);
    }
    catch (const StringException& e)
    {
        LOG_FATAL(logger, "could not read mesh file %s (%s: %s).", input_filepath.c_str(), e.what(), e.string());
    }
    catch (const exception& e)
    {
        LOG_FATAL(logger, "could not read mesh file %s (%s).", input_filepath.c_str(), e.what());
    }

    // Write the output mesh file.
    GenericMeshFileWriter writer(output_filepath.c_str());
    try
    {
        for (const_each<list<Mesh> > i = builder.get_meshes(); i; ++i)
        {
            const MeshWalker walker(*i);
            writer.write(walker);
        }
    }
    catch (const StringException& e)
    {
        LOG_FATAL(logger, "could not read mesh file %s (%s: %s).", output_filepath.c_str(), e.what(), e.string());
    }
    catch (const exception& e)
    {
        LOG_FATAL(logger, "could not write mesh file %s (%s).", output_filepath.c_str(), e.what());
    }

    return 0;
}
<|endoftext|>