<commit_before>/*
Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.

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.
*/

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <vector>

#include "SEA3D/SEA3D.h"
#include "SEA3D/ByteArray.h"

#include "o3dgc/o3dgcCommon.h"
#include "o3dgc/o3dgcVector.h"
#include "o3dgc/o3dgcSC3DMCEncodeParams.h"
#include "o3dgc/o3dgcIndexedFaceSet.h"
#include "o3dgc/o3dgcSC3DMCEncoder.h"
#include "o3dgc/o3dgcSC3DMCDecoder.h"
#include "o3dgc/o3dgcTimer.h"
#include "o3dgc/o3dgcDVEncodeParams.h"
#include "o3dgc/o3dgcDynamicVectorEncoder.h"
#include "o3dgc/o3dgcDynamicVectorDecoder.h"

#ifdef _WIN32
  #include <io.h>
  #include <fcntl.h>
#endif

using namespace o3dgc;
using namespace std;

void print(string str)
{
	for (unsigned int i = 0; i < str.size(); i++) cout << str[i];
	cout << endl;
}

unsigned char * convertToGeometryGC(
	SEAGeometry * geo,
	unsigned int & bufferLen,
	int qcoord,
    int qtexCoord,
    int qnormal,
	int qcolor,
    int qweights
	)
{
	// init

	unsigned int nIntAttributes = 0;
	unsigned int nFloatAttributes = 0;

	SC3DMCEncodeParams params;
	params.SetStreamType(O3DGC_STREAM_TYPE_BINARY);
	IndexedFaceSet<unsigned int> ifs;

	// indexes

	ifs.SetNCoordIndex((unsigned int)geo->numIndexes);
	ifs.SetCoordIndex((unsigned int * const)geo->indexes);

	if (geo->numGroups > 1)
	{
		unsigned long *groups = (unsigned long*)malloc(sizeof(unsigned long) * geo->numIndexes);

		for (unsigned int i = 0, offset = 0; i < geo->numGroups; i++)
		{
			unsigned int total = geo->counts[i];

			total += offset;

			while (offset < total)
			{
				groups[offset++] = i;
			}
		}

		ifs.SetIndexBufferID( groups );
	}

	// position

	params.SetCoordQuantBits(qcoord);
    params.SetCoordPredMode(O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION);
	ifs.SetNCoord(geo->numVertex);
	ifs.SetCoord((float * const)geo->vertex);

	// normal

	if (geo->normal != NULL)
	{
		params.SetNormalQuantBits(qnormal);
		params.SetNormalPredMode(O3DGC_SC3DMC_SURF_NORMALS_PREDICTION);
		ifs.SetNNormal(geo->numVertex);
		ifs.SetNormal((float * const)geo->normal);
	}

	// uv

	if (geo->numUV > 0)
	{
		for (unsigned int i = 0; i < geo->numUV; i++)
		{
			params.SetFloatAttributeQuantBits(nFloatAttributes, qtexCoord);
			params.SetFloatAttributePredMode(nFloatAttributes, O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION);
			ifs.SetNFloatAttribute(nFloatAttributes, geo->numVertex);
			ifs.SetFloatAttributeDim(nFloatAttributes, 2);
			ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD);
			ifs.SetFloatAttribute(nFloatAttributes, (float * const)geo->uv[i]);
			nFloatAttributes++;
		}
	}

	// joint / weight

	if (geo->jointPerVertex > 0)
	{
        ifs.SetNIntAttribute(nIntAttributes, geo->numVertex);
		ifs.SetIntAttributeDim(nIntAttributes, geo->jointPerVertex);
        ifs.SetIntAttributeType(nIntAttributes, O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID);
		ifs.SetIntAttribute(nIntAttributes, (long * const)geo->joint);
        nIntAttributes++;

		params.SetFloatAttributeQuantBits(nFloatAttributes, qweights);
		params.SetFloatAttributePredMode(nFloatAttributes, O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION);
        ifs.SetNFloatAttribute(nFloatAttributes, geo->numVertex);
		ifs.SetFloatAttributeDim(nFloatAttributes, geo->jointPerVertex);
        ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_WEIGHT);
		ifs.SetFloatAttribute(nFloatAttributes, (float * const)geo->weight);
        nFloatAttributes++;
	}

	// compute Open3DGC geometry

	params.SetNumIntAttributes(nIntAttributes);
    ifs.SetNumIntAttributes(nIntAttributes);

	params.SetNumFloatAttributes(nFloatAttributes);
    ifs.SetNumFloatAttributes(nFloatAttributes);

    ifs.ComputeMinMax(O3DGC_SC3DMC_MAX_ALL_DIMS); // O3DGC_SC3DMC_DIAG_BB

	BinaryStream bstream((geo->numVertex * 3) * 8);

	SC3DMCEncoder<unsigned int> encoder;

    encoder.Encode(params, ifs, bstream);

	// create GeometryGC

	nIntAttributes = 0;
	nFloatAttributes = 0;

	unsigned char * s3dBuffer = bstream.GetBuffer();
	unsigned int s3dSize = bstream.GetSize();

	unsigned char * buffer = new unsigned char[s3dSize + 1024]; // 1024 is header buffer
	unsigned int bufferPos = 2; // first value is attribs

	int attribs = geo->isBig ? 1 : 0;

	// write groups

	if (geo->numGroups > 1)
	{
		attribs |= 2;

		buffer[bufferPos++] = geo->numGroups;

		for (unsigned int i = 0; i < geo->numGroups; i++)
		{
			unsigned int numTris = geo->counts[i];

			buffer[bufferPos++] = numTris;
			buffer[bufferPos++] = numTris >> 8;

			if (geo->isBig)
			{
				buffer[bufferPos++] = numTris >> 16;
				buffer[bufferPos++] = numTris >> 24;
			}
		}
	}

	// write uvs

	if (geo->numUV > 0)
	{
		attribs |= 4;

		buffer[bufferPos++] = geo->numUV;

		for (unsigned int i = 0; i < geo->numUV; i++)
		{
			buffer[bufferPos++] = nFloatAttributes++;
		}
	}

	// write joint/weight

	if (geo->jointPerVertex > 0)
	{
		attribs |= 32;

		buffer[bufferPos++] = nIntAttributes++;
		buffer[bufferPos++] =  nFloatAttributes++;
	}

	// write buffer size

	buffer[bufferPos++] = s3dSize;
	buffer[bufferPos++] = s3dSize >> 8;
	buffer[bufferPos++] = s3dSize >> 16;
	buffer[bufferPos++] = s3dSize >> 24;

	// write attribs ( flags )

	buffer[0] = attribs;
	buffer[1] = attribs >> 8;

	memcpy(buffer + bufferPos, s3dBuffer, s3dSize);

	bufferLen = s3dSize + bufferPos;

	return buffer;

}

int main(int argc, char * argv[])
{
	string input, output;

	float
		qposition_quality = 1,
		qgradient_quality = 1;

	for(int i = 1; i < argc; ++i)
    {
        if ( !strcmp(argv[i], "-i"))
        {
            if (++i < argc)
            {
                input = argv[i];
            }
        }
		else if ( !strcmp(argv[i], "-o"))
        {
            if (++i < argc)
            {
                output = argv[i];
            }
        }
		else if ( !strcmp(argv[i], "-qp"))
        {
            if (++i < argc)
            {
                qposition_quality = atof(argv[i]);
            }
        }
		else if ( !strcmp(argv[i], "-qg"))
        {
            if (++i < argc)
            {
                qgradient_quality = atof(argv[i]);
            }
        }
	}

	int qcoord = (int)(12 * qposition_quality);
    int qtexCoord = (int)(10 * qgradient_quality);
    int qnormal = (int)(10 * qgradient_quality);
	int qcolor = (int)(10 * qgradient_quality);
    int qweights = (int)(8 * qgradient_quality);

	if (qposition_quality < 0.1) qposition_quality = 0.1;
	else if (qposition_quality > 2) qposition_quality = 2;

	if (qgradient_quality < 0.1) qgradient_quality = 0.1;
	else if (qgradient_quality > 2) qgradient_quality = 2;

	//input = "D:\\Sunag\\Github\\sea3d_sdk\\Source\\O3DGC\\Debug\\Object002.geo";
	//input = "D:\\Sunag\\Github\\sea3d_sdk\\Source\\O3DGC\\Debug\\temp-14.geo";
	//output = "D:\\Sunag\\Github\\sea3d_sdk\\Source\\O3DGC\\Debug\\Object002.s3D";

	if (input.empty() || output.empty())
	{
		cout << "Convert SEAGeometry to SEAGeometryGC example: SEA3DLossyCompress.exe -i sea3d_geometry.geo -o sea3d_o3dgc.s3D";
		return 1;
	}

	ByteArray istream;
	istream.fromFile( input.c_str() );

	SEAGeometry geo;
	geo.read( istream );

	unsigned int geoGCSize;
	unsigned char * geoGCBuffer = convertToGeometryGC(&geo, geoGCSize, qcoord, qtexCoord, qnormal, qcolor, qweights);

	ByteArray ostream;
	ostream.fromBuffer(geoGCBuffer, geoGCSize);
	ostream.saveFile( output.c_str() );

}<commit_msg>fix quality<commit_after>/*
Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.

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.
*/

#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <vector>

#include "SEA3D/SEA3D.h"
#include "SEA3D/ByteArray.h"

#include "o3dgc/o3dgcCommon.h"
#include "o3dgc/o3dgcVector.h"
#include "o3dgc/o3dgcSC3DMCEncodeParams.h"
#include "o3dgc/o3dgcIndexedFaceSet.h"
#include "o3dgc/o3dgcSC3DMCEncoder.h"
#include "o3dgc/o3dgcSC3DMCDecoder.h"
#include "o3dgc/o3dgcTimer.h"
#include "o3dgc/o3dgcDVEncodeParams.h"
#include "o3dgc/o3dgcDynamicVectorEncoder.h"
#include "o3dgc/o3dgcDynamicVectorDecoder.h"

#ifdef _WIN32
  #include <io.h>
  #include <fcntl.h>
#endif

using namespace o3dgc;
using namespace std;

void print(string str)
{
	for (unsigned int i = 0; i < str.size(); i++) cout << str[i];
	cout << endl;
}

unsigned char * convertToGeometryGC(
	SEAGeometry * geo,
	unsigned int & bufferLen,
	int qcoord,
    int qtexCoord,
    int qnormal,
	int qcolor,
    int qweights
	)
{
	// init

	unsigned int nIntAttributes = 0;
	unsigned int nFloatAttributes = 0;

	SC3DMCEncodeParams params;
	params.SetStreamType(O3DGC_STREAM_TYPE_BINARY);
	IndexedFaceSet<unsigned int> ifs;

	// indexes

	ifs.SetNCoordIndex((unsigned int)geo->numIndexes);
	ifs.SetCoordIndex((unsigned int * const)geo->indexes);

	if (geo->numGroups > 1)
	{
		unsigned long *groups = (unsigned long*)malloc(sizeof(unsigned long) * geo->numIndexes);

		for (unsigned int i = 0, offset = 0; i < geo->numGroups; i++)
		{
			unsigned int total = geo->counts[i];

			total += offset;

			while (offset < total)
			{
				groups[offset++] = i;
			}
		}

		ifs.SetIndexBufferID( groups );
	}

	// position

	params.SetCoordQuantBits(qcoord);
    params.SetCoordPredMode(O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION);
	ifs.SetNCoord(geo->numVertex);
	ifs.SetCoord((float * const)geo->vertex);

	// normal

	if (geo->normal != NULL)
	{
		params.SetNormalQuantBits(qnormal);
		params.SetNormalPredMode(O3DGC_SC3DMC_SURF_NORMALS_PREDICTION);
		ifs.SetNNormal(geo->numVertex);
		ifs.SetNormal((float * const)geo->normal);
	}

	// uv

	if (geo->numUV > 0)
	{
		for (unsigned int i = 0; i < geo->numUV; i++)
		{
			params.SetFloatAttributeQuantBits(nFloatAttributes, qtexCoord);
			params.SetFloatAttributePredMode(nFloatAttributes, O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION);
			ifs.SetNFloatAttribute(nFloatAttributes, geo->numVertex);
			ifs.SetFloatAttributeDim(nFloatAttributes, 2);
			ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD);
			ifs.SetFloatAttribute(nFloatAttributes, (float * const)geo->uv[i]);
			nFloatAttributes++;
		}
	}

	// joint / weight

	if (geo->jointPerVertex > 0)
	{
        ifs.SetNIntAttribute(nIntAttributes, geo->numVertex);
		ifs.SetIntAttributeDim(nIntAttributes, geo->jointPerVertex);
        ifs.SetIntAttributeType(nIntAttributes, O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID);
		ifs.SetIntAttribute(nIntAttributes, (long * const)geo->joint);
        nIntAttributes++;

		params.SetFloatAttributeQuantBits(nFloatAttributes, qweights);
		params.SetFloatAttributePredMode(nFloatAttributes, O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION);
        ifs.SetNFloatAttribute(nFloatAttributes, geo->numVertex);
		ifs.SetFloatAttributeDim(nFloatAttributes, geo->jointPerVertex);
        ifs.SetFloatAttributeType(nFloatAttributes, O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_WEIGHT);
		ifs.SetFloatAttribute(nFloatAttributes, (float * const)geo->weight);
        nFloatAttributes++;
	}

	// compute Open3DGC geometry

	params.SetNumIntAttributes(nIntAttributes);
    ifs.SetNumIntAttributes(nIntAttributes);

	params.SetNumFloatAttributes(nFloatAttributes);
    ifs.SetNumFloatAttributes(nFloatAttributes);

    ifs.ComputeMinMax(O3DGC_SC3DMC_MAX_ALL_DIMS); // O3DGC_SC3DMC_DIAG_BB

	BinaryStream bstream((geo->numVertex * 3) * 8);

	SC3DMCEncoder<unsigned int> encoder;

    encoder.Encode(params, ifs, bstream);

	// create GeometryGC

	nIntAttributes = 0;
	nFloatAttributes = 0;

	unsigned char * s3dBuffer = bstream.GetBuffer();
	unsigned int s3dSize = bstream.GetSize();

	unsigned char * buffer = new unsigned char[s3dSize + 1024]; // 1024 is header buffer
	unsigned int bufferPos = 2; // first value is attribs

	int attribs = geo->isBig ? 1 : 0;

	// write groups

	if (geo->numGroups > 1)
	{
		attribs |= 2;

		buffer[bufferPos++] = geo->numGroups;

		for (unsigned int i = 0; i < geo->numGroups; i++)
		{
			unsigned int numTris = geo->counts[i];

			buffer[bufferPos++] = numTris;
			buffer[bufferPos++] = numTris >> 8;

			if (geo->isBig)
			{
				buffer[bufferPos++] = numTris >> 16;
				buffer[bufferPos++] = numTris >> 24;
			}
		}
	}

	// write uvs

	if (geo->numUV > 0)
	{
		attribs |= 4;

		buffer[bufferPos++] = geo->numUV;

		for (unsigned int i = 0; i < geo->numUV; i++)
		{
			buffer[bufferPos++] = nFloatAttributes++;
		}
	}

	// write joint/weight

	if (geo->jointPerVertex > 0)
	{
		attribs |= 32;

		buffer[bufferPos++] = nIntAttributes++;
		buffer[bufferPos++] =  nFloatAttributes++;
	}

	// write buffer size

	buffer[bufferPos++] = s3dSize;
	buffer[bufferPos++] = s3dSize >> 8;
	buffer[bufferPos++] = s3dSize >> 16;
	buffer[bufferPos++] = s3dSize >> 24;

	// write attribs ( flags )

	buffer[0] = attribs;
	buffer[1] = attribs >> 8;

	memcpy(buffer + bufferPos, s3dBuffer, s3dSize);

	bufferLen = s3dSize + bufferPos;

	return buffer;

}

int main(int argc, char * argv[])
{
	string input, output;

	double
		qposition_quality = 1,
		qgradient_quality = 1;

	for(int i = 1; i < argc; ++i)
    {
        if ( !strcmp(argv[i], "-i"))
        {
            if (++i < argc)
            {
                input = argv[i];
            }
        }
		else if ( !strcmp(argv[i], "-o"))
        {
            if (++i < argc)
            {
                output = argv[i];
            }
        }
		else if ( !strcmp(argv[i], "-qp"))
        {
            if (++i < argc)
            {
                qposition_quality = atof(argv[i]);
            }
        }
		else if ( !strcmp(argv[i], "-qg"))
        {
            if (++i < argc)
            {
                qgradient_quality = atof(argv[i]);
            }
        }
	}

	int qcoord = (int)(12 * qposition_quality);
    int qtexCoord = (int)(15 * qgradient_quality);
    int qnormal = (int)(12 * qgradient_quality);
	int qcolor = (int)(12 * qgradient_quality);
    int qweights = (int)(10 * qgradient_quality);

	if (qposition_quality < 0.1) qposition_quality = 0.1;
	else if (qposition_quality > 2) qposition_quality = 2;

	if (qgradient_quality < 0.1) qgradient_quality = 0.1;
	else if (qgradient_quality > 2) qgradient_quality = 2;

	//input = "D:\\Sunag\\Github\\sea3d_sdk\\Source\\O3DGC\\Debug\\Object002.geo";
	//input = "D:\\Sunag\\Github\\sea3d_sdk\\Source\\O3DGC\\Debug\\temp-14.geo";
	//output = "D:\\Sunag\\Github\\sea3d_sdk\\Source\\O3DGC\\Debug\\Object002.s3D";

	if (input.empty() || output.empty())
	{
		cout << "Convert SEAGeometry to SEAGeometryGC example: SEA3DLossyCompress.exe -i sea3d_geometry.geo -o sea3d_o3dgc.s3D";
		return 1;
	}

	ByteArray istream;
	istream.fromFile( input.c_str() );

	SEAGeometry geo;
	geo.read( istream );

	unsigned int geoGCSize;
	unsigned char * geoGCBuffer = convertToGeometryGC(&geo, geoGCSize, qcoord, qtexCoord, qnormal, qcolor, qweights);

	ByteArray ostream;
	ostream.fromBuffer(geoGCBuffer, geoGCSize);
	ostream.saveFile( output.c_str() );

}<|endoftext|>


<commit_before>#pragma once
#include <bts/blockchain/chain_database.hpp>
#include <bts/wallet/wallet.hpp>
#include <bts/net/node.hpp>
#include <bts/rpc/rpc_client_api.hpp>
#include <bts/api/common_api.hpp>
#include <bts/rpc_stubs/common_api_client.hpp>
#include <fc/thread/thread.hpp>
#include <fc/log/logger_config.hpp>
#include <memory>
#include <boost/program_options.hpp>

namespace bts { namespace rpc {
  class rpc_server;
  typedef std::shared_ptr<rpc_server> rpc_server_ptr;
} }
namespace bts { namespace cli {
    class cli;
}};

namespace bts { namespace client {

    using namespace bts::blockchain;
    using namespace bts::wallet;
    using namespace bts::mail;

    boost::program_options::variables_map parse_option_variables(int argc, char** argv);
    fc::path get_data_dir(const boost::program_options::variables_map& option_variables);
    fc::variant_object version_info();

    namespace detail { class client_impl; }

    using namespace bts::rpc;

    struct rpc_server_config
    {
      rpc_server_config()
      : enable(false),
        rpc_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        httpd_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        htdocs("./htdocs")
      {}

      bool             enable;
      std::string      rpc_user;
      std::string      rpc_password;
      fc::ip::endpoint rpc_endpoint;
      fc::ip::endpoint httpd_endpoint;
      fc::path         htdocs;

      bool is_valid() const; /* Currently just checks if rpc port is set */
    };

    struct chain_server_config
    {
        chain_server_config()
         : enabled(false),
           listen_port(0)
        {}

        bool enabled;
        uint16_t listen_port;
    };

    struct config
    {
       config( ) :
          default_peers(vector<string>{"104.131.204.143:", "54.77.61.238:", "54.207.13.136:", "54.169.39.185"}),
          mail_server_enabled(false),
          wallet_enabled(true),
          ignore_console(false),
          use_upnp(true),
          maximum_number_of_connections(BTS_NET_DEFAULT_MAX_CONNECTIONS) ,
          delegate_server( fc::ip::endpoint::from_string("0.0.0.0:0") ),
          default_delegate_peers( vector<string>({"107.170.30.182:9988"}) )
          {
#ifdef BTS_TEST_NETWORK
              uint32_t port = BTS_NET_TEST_P2P_PORT + BTS_TEST_NETWORK_VERSION;
#else
              uint32_t port = BTS_NET_DEFAULT_P2P_PORT;
#endif
              default_peers[0] += fc::to_string( port );
              default_peers[1] += fc::to_string( port + 100 );
              default_peers[2] += fc::to_string( port + 200 );
              logging = fc::logging_config::default_config();
          }

          rpc_server_config   rpc;
          vector<string>      default_peers;
          vector<string>      chain_servers;
          chain_server_config chain_server;
          bool                mail_server_enabled;
          bool                wallet_enabled;
          bool                ignore_console;
          bool                use_upnp;
          optional<fc::path>  genesis_config;
          uint16_t            maximum_number_of_connections;
          fc::logging_config  logging;
          fc::ip::endpoint    delegate_server;
          vector<string>      default_delegate_peers;

          fc::optional<std::string> growl_notify_endpoint;
          fc::optional<std::string> growl_password;
          fc::optional<std::string> growl_bitshares_client_identifier;
    };

    /**
     * @class client
     * @brief integrates the network, wallet, and blockchain
     *
     */
    class client : public bts::rpc_stubs::common_api_client,
                   public std::enable_shared_from_this<client>
    {
       public:
         client();
         client(bts::net::simulated_network_ptr network_to_connect_to);

         void simulate_disconnect( bool state );

         virtual ~client();

         void start_networking(std::function<void()> network_started_callback = std::function<void()>());
         void configure_from_command_line(int argc, char** argv);
         fc::future<void> start();
         void open(const path& data_dir,
                   optional<fc::path> genesis_file_path = optional<fc::path>(),
                   std::function<void(float)> reindex_status_callback = std::function<void(float)>());

         void init_cli();
         void set_daemon_mode(bool daemon_mode);

         chain_database_ptr         get_chain()const;
         wallet_ptr                 get_wallet()const;
         mail_server_ptr            get_mail_server()const;
         bts::rpc::rpc_server_ptr   get_rpc_server()const;
         bts::net::node_ptr         get_node()const;
         fc::path                   get_data_dir()const;

         // returns true if the client is connected to the network
         bool                is_connected() const;
         bts::net::node_id_t get_node_id() const;

         const config& configure(const fc::path& configuration_directory);

         // functions for taking command-line parameters and passing them on to the p2p node
         void listen_on_port( uint16_t port_to_listen, bool wait_if_not_available);
         void accept_incoming_p2p_connections(bool accept);
         void listen_to_p2p_network();
         static fc::ip::endpoint string_to_endpoint(const std::string& remote_endpoint);
         void add_node( const string& remote_endpoint );
         void connect_to_peer( const string& remote_endpoint );
         void connect_to_p2p_network();

         fc::ip::endpoint get_p2p_listening_endpoint() const;
         bool handle_message(const bts::net::message&, bool sync_mode);
         void sync_status(uint32_t item_type, uint32_t item_count);

       protected:
         virtual bts::api::common_api* get_impl() const override;

       private:
         unique_ptr<detail::client_impl> my;
    };

    typedef shared_ptr<client> client_ptr;

    /* Message broadcast on the network to notify all clients of some important information
      (security vulnerability, new version, that sort of thing) */
    class client_notification
    {
       public:
         fc::time_point_sec         timestamp;
         string                message;
         fc::ecc::compact_signature signature;

         //client_notification();
         fc::sha256 digest() const;
         void sign(const fc::ecc::private_key& key);
         fc::ecc::public_key signee() const;
    };
    typedef shared_ptr<client_notification> client_notification_ptr;

} } // bts::client

extern const std::string BTS_MESSAGE_MAGIC;

FC_REFLECT(bts::client::client_notification, (timestamp)(message)(signature) )
FC_REFLECT( bts::client::rpc_server_config, (enable)(rpc_user)(rpc_password)(rpc_endpoint)(httpd_endpoint)(htdocs) )
FC_REFLECT( bts::client::chain_server_config, (enabled)(listen_port) )
FC_REFLECT( bts::client::config,
            (rpc)(default_peers)(chain_servers)(chain_server)(mail_server_enabled)
            (wallet_enabled)(ignore_console)(logging)
            (delegate_server)
            (default_delegate_peers)
            (growl_notify_endpoint)
            (growl_password)
            (growl_bitshares_client_identifier) )

<commit_msg>Fix seed node ports<commit_after>#pragma once
#include <bts/blockchain/chain_database.hpp>
#include <bts/wallet/wallet.hpp>
#include <bts/net/node.hpp>
#include <bts/rpc/rpc_client_api.hpp>
#include <bts/api/common_api.hpp>
#include <bts/rpc_stubs/common_api_client.hpp>
#include <fc/thread/thread.hpp>
#include <fc/log/logger_config.hpp>
#include <memory>
#include <boost/program_options.hpp>

namespace bts { namespace rpc {
  class rpc_server;
  typedef std::shared_ptr<rpc_server> rpc_server_ptr;
} }
namespace bts { namespace cli {
    class cli;
}};

namespace bts { namespace client {

    using namespace bts::blockchain;
    using namespace bts::wallet;
    using namespace bts::mail;

    boost::program_options::variables_map parse_option_variables(int argc, char** argv);
    fc::path get_data_dir(const boost::program_options::variables_map& option_variables);
    fc::variant_object version_info();

    namespace detail { class client_impl; }

    using namespace bts::rpc;

    struct rpc_server_config
    {
      rpc_server_config()
      : enable(false),
        rpc_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        httpd_endpoint(fc::ip::endpoint::from_string("127.0.0.1:0")),
        htdocs("./htdocs")
      {}

      bool             enable;
      std::string      rpc_user;
      std::string      rpc_password;
      fc::ip::endpoint rpc_endpoint;
      fc::ip::endpoint httpd_endpoint;
      fc::path         htdocs;

      bool is_valid() const; /* Currently just checks if rpc port is set */
    };

    struct chain_server_config
    {
        chain_server_config()
         : enabled(false),
           listen_port(0)
        {}

        bool enabled;
        uint16_t listen_port;
    };

    struct config
    {
       config( ) :
          default_peers(vector<string>{"104.131.204.143:", "54.77.61.238:", "54.207.13.136:", "54.169.39.185:"}),
          mail_server_enabled(false),
          wallet_enabled(true),
          ignore_console(false),
          use_upnp(true),
          maximum_number_of_connections(BTS_NET_DEFAULT_MAX_CONNECTIONS) ,
          delegate_server( fc::ip::endpoint::from_string("0.0.0.0:0") ),
          default_delegate_peers( vector<string>({"107.170.30.182:9988"}) )
          {
#ifdef BTS_TEST_NETWORK
              uint32_t port = BTS_NET_TEST_P2P_PORT + BTS_TEST_NETWORK_VERSION;
              default_peers[0] += fc::to_string( port );
              default_peers[1] += fc::to_string( port + 100 );
              default_peers[2] += fc::to_string( port + 200 );
#else
              uint32_t port = BTS_NET_DEFAULT_P2P_PORT;
              default_peers[0] += fc::to_string( port );
              default_peers[1] += fc::to_string( port );
              default_peers[2] += fc::to_string( port );
              default_peers[3] += fc::to_string( port );
#endif
              logging = fc::logging_config::default_config();
          }

          rpc_server_config   rpc;
          vector<string>      default_peers;
          vector<string>      chain_servers;
          chain_server_config chain_server;
          bool                mail_server_enabled;
          bool                wallet_enabled;
          bool                ignore_console;
          bool                use_upnp;
          optional<fc::path>  genesis_config;
          uint16_t            maximum_number_of_connections;
          fc::logging_config  logging;
          fc::ip::endpoint    delegate_server;
          vector<string>      default_delegate_peers;

          fc::optional<std::string> growl_notify_endpoint;
          fc::optional<std::string> growl_password;
          fc::optional<std::string> growl_bitshares_client_identifier;
    };

    /**
     * @class client
     * @brief integrates the network, wallet, and blockchain
     *
     */
    class client : public bts::rpc_stubs::common_api_client,
                   public std::enable_shared_from_this<client>
    {
       public:
         client();
         client(bts::net::simulated_network_ptr network_to_connect_to);

         void simulate_disconnect( bool state );

         virtual ~client();

         void start_networking(std::function<void()> network_started_callback = std::function<void()>());
         void configure_from_command_line(int argc, char** argv);
         fc::future<void> start();
         void open(const path& data_dir,
                   optional<fc::path> genesis_file_path = optional<fc::path>(),
                   std::function<void(float)> reindex_status_callback = std::function<void(float)>());

         void init_cli();
         void set_daemon_mode(bool daemon_mode);

         chain_database_ptr         get_chain()const;
         wallet_ptr                 get_wallet()const;
         mail_server_ptr            get_mail_server()const;
         bts::rpc::rpc_server_ptr   get_rpc_server()const;
         bts::net::node_ptr         get_node()const;
         fc::path                   get_data_dir()const;

         // returns true if the client is connected to the network
         bool                is_connected() const;
         bts::net::node_id_t get_node_id() const;

         const config& configure(const fc::path& configuration_directory);

         // functions for taking command-line parameters and passing them on to the p2p node
         void listen_on_port( uint16_t port_to_listen, bool wait_if_not_available);
         void accept_incoming_p2p_connections(bool accept);
         void listen_to_p2p_network();
         static fc::ip::endpoint string_to_endpoint(const std::string& remote_endpoint);
         void add_node( const string& remote_endpoint );
         void connect_to_peer( const string& remote_endpoint );
         void connect_to_p2p_network();

         fc::ip::endpoint get_p2p_listening_endpoint() const;
         bool handle_message(const bts::net::message&, bool sync_mode);
         void sync_status(uint32_t item_type, uint32_t item_count);

       protected:
         virtual bts::api::common_api* get_impl() const override;

       private:
         unique_ptr<detail::client_impl> my;
    };

    typedef shared_ptr<client> client_ptr;

    /* Message broadcast on the network to notify all clients of some important information
      (security vulnerability, new version, that sort of thing) */
    class client_notification
    {
       public:
         fc::time_point_sec         timestamp;
         string                message;
         fc::ecc::compact_signature signature;

         //client_notification();
         fc::sha256 digest() const;
         void sign(const fc::ecc::private_key& key);
         fc::ecc::public_key signee() const;
    };
    typedef shared_ptr<client_notification> client_notification_ptr;

} } // bts::client

extern const std::string BTS_MESSAGE_MAGIC;

FC_REFLECT(bts::client::client_notification, (timestamp)(message)(signature) )
FC_REFLECT( bts::client::rpc_server_config, (enable)(rpc_user)(rpc_password)(rpc_endpoint)(httpd_endpoint)(htdocs) )
FC_REFLECT( bts::client::chain_server_config, (enabled)(listen_port) )
FC_REFLECT( bts::client::config,
            (rpc)(default_peers)(chain_servers)(chain_server)(mail_server_enabled)
            (wallet_enabled)(ignore_console)(logging)
            (delegate_server)
            (default_delegate_peers)
            (growl_notify_endpoint)
            (growl_password)
            (growl_bitshares_client_identifier) )

<|endoftext|>


<commit_before>/* +---------------------------------------------------------------------------+
   |                 The Mobile Robot Programming Toolkit (MRPT)               |
   |                                                                           |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file        |
   | Copyright (c) 2005-2013, MAPIR group, University of Malaga                |
   | Copyright (c) 2012-2013, University of Almeria                            |
   | 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 copyright holders 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 THE COPYRIGHT HOLDERS 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 <mrpt/base.h>
#include <gtest/gtest.h>

using namespace mrpt;
using namespace mrpt::slam;
using namespace mrpt::utils;
using namespace mrpt::math;
using namespace std;

// Defined in run_unittests.cpp
namespace mrpt { namespace utils {
	extern std::string MRPT_GLOBAL_UNITTEST_SRC_DIR;
  }
}

// Load data from constant file and check for exact match.
TEST(SerializeTestBase, LoadDemoFile)
{
	struct TRegs
	{
		uint8_t		v1;
		int8_t		v2;
		uint16_t	v3;
		int16_t		v4;
		uint32_t	v5;
		int32_t		v6;
		uint64_t	v7;
		int64_t		v8;
		std::string 	v9;
	};

	// Reference data:
	TRegs	R;
	R.v1 = 8;
	R.v2 = -3;
	R.v3 = 781;
	R.v4 = -888;
	R.v5 =  100000;
	R.v6 = -100000;
	R.v7 =  555666777;
	R.v8 = -555666777;
	R.v9 = "an example test";

	// Loaded data to compare with reference:
	TRegs	L;
	const string fil = MRPT_GLOBAL_UNITTEST_SRC_DIR + string("/tests/serialize_test_data.bin");

	if (!mrpt::system::fileExists(fil))
	{
		cerr << "WARNING: Skipping test due to missing file: " << fil << "\n";
	}
	else
	{
		CFileInputStream	gg( fil );
		gg >> L.v1 >> L.v2 >> L.v3 >> L.v4 >> L.v5 >> L.v6 >> L.v7 >> L.v8 >> L.v9;

		EXPECT_EQ(R.v1,L.v1 );
		EXPECT_EQ(R.v2,L.v2 );
		EXPECT_EQ(R.v3,L.v3 );
		EXPECT_EQ(R.v4,L.v4 );
		EXPECT_EQ(R.v5,L.v5 );
		EXPECT_EQ(R.v6,L.v6 );
		EXPECT_EQ(R.v7,L.v7 );
		EXPECT_EQ(R.v8,L.v8 );
		EXPECT_EQ(R.v9,L.v9 );
	}
}

// Create a set of classes, then serialize and deserialize to test possible bugs:
TEST(SerializeTestBase, WriteReadToMem)
{
	const mrpt::utils::TRuntimeClassId* lstClasses[] = {
		// Misc:
		CLASS_ID(CPose2D),
		CLASS_ID(CPose3D),
		CLASS_ID(CPose3DQuat),
		CLASS_ID(CPoint2D),
		CLASS_ID(CPoint3D),
		// Poses:
		CLASS_ID(CPose3DPDFGaussian),
		CLASS_ID(CPose3DQuatPDFGaussian)
		};

	for (size_t i=0;i<sizeof(lstClasses)/sizeof(lstClasses[0]);i++)
	{
		try
		{
			CMemoryStream  buf;
			{
				CSerializable* o = static_cast<CSerializable*>(lstClasses[i]->createObject());
				buf << *o;
				delete o;
			}

			CSerializablePtr recons;
			buf.Seek(0);
			buf >> recons;
		}
		catch(std::exception &e)
		{
			GTEST_FAIL() <<
				"Exception during serialization test for class '"<< lstClasses[i]->className <<"':\n" << e.what() << endl;
		}
	}
}

// Create a set of classes, then serialize and deserialize to test possible bugs:
TEST(SerializeTestBase, CArray)
{
	try
	{
		CMemoryStream  buf;
		CArrayDouble<5>  a, b;
		for (CArrayDouble<5>::Index i=0;i<a.size();i++) a[i] = i+10;

		buf << a;
		buf.Seek(0);
		buf >> b;

		EXPECT_TRUE(a==b);
	}
	catch(std::exception &e)
	{
		GTEST_FAIL() <<
			"Exception:\n" << e.what() << endl;
	}

}

<commit_msg>New STL serialization unit test<commit_after>/* +---------------------------------------------------------------------------+
   |                 The Mobile Robot Programming Toolkit (MRPT)               |
   |                                                                           |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file        |
   | Copyright (c) 2005-2013, MAPIR group, University of Malaga                |
   | Copyright (c) 2012-2013, University of Almeria                            |
   | 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 copyright holders 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 THE COPYRIGHT HOLDERS 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 <mrpt/base.h>
#include <gtest/gtest.h>

using namespace mrpt;
using namespace mrpt::slam;
using namespace mrpt::utils;
using namespace mrpt::math;
using namespace std;

// Defined in run_unittests.cpp
namespace mrpt { namespace utils {
	extern std::string MRPT_GLOBAL_UNITTEST_SRC_DIR;
  }
}

// Load data from constant file and check for exact match.
TEST(SerializeTestBase, LoadDemoFile)
{
	struct TRegs
	{
		uint8_t		v1;
		int8_t		v2;
		uint16_t	v3;
		int16_t		v4;
		uint32_t	v5;
		int32_t		v6;
		uint64_t	v7;
		int64_t		v8;
		std::string 	v9;
	};

	// Reference data:
	TRegs	R;
	R.v1 = 8;
	R.v2 = -3;
	R.v3 = 781;
	R.v4 = -888;
	R.v5 =  100000;
	R.v6 = -100000;
	R.v7 =  555666777;
	R.v8 = -555666777;
	R.v9 = "an example test";

	// Loaded data to compare with reference:
	TRegs	L;
	const string fil = MRPT_GLOBAL_UNITTEST_SRC_DIR + string("/tests/serialize_test_data.bin");

	if (!mrpt::system::fileExists(fil))
	{
		cerr << "WARNING: Skipping test due to missing file: " << fil << "\n";
	}
	else
	{
		CFileInputStream	gg( fil );
		gg >> L.v1 >> L.v2 >> L.v3 >> L.v4 >> L.v5 >> L.v6 >> L.v7 >> L.v8 >> L.v9;

		EXPECT_EQ(R.v1,L.v1 );
		EXPECT_EQ(R.v2,L.v2 );
		EXPECT_EQ(R.v3,L.v3 );
		EXPECT_EQ(R.v4,L.v4 );
		EXPECT_EQ(R.v5,L.v5 );
		EXPECT_EQ(R.v6,L.v6 );
		EXPECT_EQ(R.v7,L.v7 );
		EXPECT_EQ(R.v8,L.v8 );
		EXPECT_EQ(R.v9,L.v9 );
	}
}

// Create a set of classes, then serialize and deserialize to test possible bugs:
TEST(SerializeTestBase, WriteReadToMem)
{
	const mrpt::utils::TRuntimeClassId* lstClasses[] = {
		// Misc:
		CLASS_ID(CPose2D),
		CLASS_ID(CPose3D),
		CLASS_ID(CPose3DQuat),
		CLASS_ID(CPoint2D),
		CLASS_ID(CPoint3D),
		// Poses:
		CLASS_ID(CPose3DPDFGaussian),
		CLASS_ID(CPose3DQuatPDFGaussian)
		};

	for (size_t i=0;i<sizeof(lstClasses)/sizeof(lstClasses[0]);i++)
	{
		try
		{
			CMemoryStream  buf;
			{
				CSerializable* o = static_cast<CSerializable*>(lstClasses[i]->createObject());
				buf << *o;
				delete o;
			}

			CSerializablePtr recons;
			buf.Seek(0);
			buf >> recons;
		}
		catch(std::exception &e)
		{
			GTEST_FAIL() <<
				"Exception during serialization test for class '"<< lstClasses[i]->className <<"':\n" << e.what() << endl;
		}
	}
}

// Create a set of classes, then serialize and deserialize to test possible bugs:
TEST(SerializeTestBase, CArray)
{
	try
	{
		CMemoryStream  buf;
		CArrayDouble<5>  a, b;
		for (CArrayDouble<5>::Index i=0;i<a.size();i++) a[i] = i+10;

		buf << a;
		buf.Seek(0);
		buf >> b;

		EXPECT_TRUE(a==b);
	}
	catch(std::exception &e)
	{
		GTEST_FAIL() <<
			"Exception:\n" << e.what() << endl;
	}

}

// Serialize and deserialize complex STL types
TEST(SerializeTestBase, STL_serialization)
{
	try
	{
		// std::vector<>
		{
			CMemoryStream  buf;

			std::vector<double> a,b;
			a.resize(30);
			for (size_t i=0;i<a.size();i++) a[i]=50-i;

			buf << a; buf.Seek(0); buf >> b;
			EXPECT_TRUE(a==b);
		}

		// std::list<...>
		{
			CMemoryStream  buf;

			std::list<std::map<double,std::set<std::string> > >  a,b;

			// Fill with random:
			mrpt::random::CRandomGenerator rng;
			const size_t N = rng.drawUniform(10,30);
			for (size_t i=0;i<N;i++)
			{
				std::map<double,std::set<std::string> > d;
				const size_t M = rng.drawUniform(4,9);
				for (size_t j=0;j<M;j++)
				{
					std::set<std::string> & dd = d[ rng.drawGaussian1D_normalized() ];
					const size_t L = rng.drawUniform(2,15);
					for (size_t k=0;k<L;k++)
						dd.insert(mrpt::format("%f", rng.drawGaussian1D_normalized() ));
				}
				a.push_back(d);
			}

			buf << a; buf.Seek(0); buf >> b;
			EXPECT_TRUE(a==b);
		}
	}
	catch(std::exception &e)
	{
		GTEST_FAIL() <<
			"Exception:\n" << e.what() << endl;
	}

}

<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Flowgrammable.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS"
// BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing
// permissions and limitations under the License.

#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
#include <map>
#include <assert.h>

#include <freeflow/sys/socket.hpp>
#include <freeflow/sys/json.hpp>

using namespace std;
using namespace freeflow;
using namespace json;

namespace cli {

using String_map = map<string, string>;
using String_list = vector<string>;

std::pair<std::string, std::string>
parse_flag(const std::string& arg) {
  // If the argument is only '-', that's an error
  if (arg.size() == 1)
    throw std::runtime_error("parse error");

  // Make sure that p points to the first non-flag character.
  std::size_t p = 1;
  if (arg[p] == '-')
    ++p;

  // If the flag is "--", that's an error.
  if (p == arg.size())
    throw std::runtime_error("parse error");

  // Parse the name from the flag. If the flag is of the from
  // f=x, this parses out f. If the '=' is not present, this
  // returns the name f.
  std::string name;
  std::size_t n = arg.find_first_of('=', p);
  if (n != arg.npos)
    name = arg.substr(p, n - p);
  else
    return {arg.substr(p), "true"};

  // Parse the value. In a flag of the form f=x, this is everything
  // past the '='. If the value is empty, return as if it were "null".
  string value = arg.substr(n + 1);
  if (value.empty())
    return {std::move(name), "null"};
  else
    return {std::move(name), std::move(value)};
}

// Parses the command line inputs into flags and positional arguments
void
parse(int argc, char *argv[], String_map& opts, String_list& args) {
  for (int i = 0; i < argc; ++i) {
    if (argv[i][0] == '-')
      opts.insert(parse_flag(argv[i]));
    else
      args.push_back(argv[i]);
  }
}

} // namespace cli

using namespace cli;

int
main(int argc, char *argv[]) {
  String_map opts;
  String_list args;

  parse(argc, argv, opts, args);

  std::cout << "== options ==\n";
  for (auto &f : opts)
    std::cout << f.first << " : " << f.second << '\n';

  std::cout << endl << "== positional args ==\n";
  for (auto &s : args)
    std::cout << s << endl;

  return 0;
}

<commit_msg>Speculative design for cli/<commit_after>// Copyright (c) 2013-2014 Flowgrammable.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS"
// BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing
// permissions and limitations under the License.

#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>
#include <map>
#include <assert.h>

#include <freeflow/sys/socket.hpp>
#include <freeflow/sys/json.hpp>

using namespace std;
using namespace freeflow;
using namespace json;

namespace cli {

using String_map = map<string, string>;
using String_list = vector<string>;

std::pair<std::string, std::string>
parse_flag(const std::string& arg) {
  // If the argument is only '-', that's an error
  if (arg.size() == 1)
    throw std::runtime_error("parse error");

  // Make sure that p points to the first non-flag character.
  std::size_t p = 1;
  if (arg[p] == '-')
    ++p;

  // If the flag is "--", that's an error.
  if (p == arg.size())
    throw std::runtime_error("parse error");

  // Parse the name from the flag. If the flag is of the from
  // f=x, this parses out f. If the '=' is not present, this
  // returns the name f.
  std::string name;
  std::size_t n = arg.find_first_of('=', p);
  if (n != arg.npos)
    name = arg.substr(p, n - p);
  else
    return {arg.substr(p), "true"};

  // Parse the value. In a flag of the form f=x, this is everything
  // past the '='. If the value is empty, return as if it were "null".
  string value = arg.substr(n + 1);
  if (value.empty())
    return {std::move(name), "null"};
  else
    return {std::move(name), std::move(value)};
}

// Parses the command line inputs into flags and positional arguments
void
parse(int argc, char *argv[], String_map& opts, String_list& args) {
  for (int i = 0; i < argc; ++i) {
    if (argv[i][0] == '-')
      opts.insert(parse_flag(argv[i]));
    else
      args.push_back(argv[i]);
  }
}

// struct Bool {
//   json::Value operator()(const std::string& s) const {

//     // Check that s is one of:
//     //    - true | false
//     //    - yes | no
//     //    - on | off

//     // Throw an exception if it isnt?

//     return true;
//   }
// };

} // namespace cli

using namespace cli;

int
main(int argc, char *argv[]) {
  String_map opts;
  String_list args;

  parse(argc, argv, opts, args);

  std::cout << "== options ==\n";
  for (auto &f : opts)
    std::cout << f.first << " : " << f.second << '\n';

  std::cout << endl << "== positional args ==\n";
  for (auto &s : args)
    std::cout << s << endl;

  // {
  //   Parameter<Bool> p1("flag", "f", "Indicate that flag is set");

  //   json::Value v1 = p1.get(opts);
  // }

  return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 Flowgrammable.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS"
// BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing
// permissions and limitations under the License.

#include <assert.h>

#include <freeflow/sys/socket.hpp>
#include <freeflow/sys/json.hpp>
#include <freeflow/sys/cli.hpp>

#include "command.hpp"

using namespace std;
using namespace freeflow;

struct Add_command : cli::Command {
  Add_command()
    : Command("add", "Add something to something else")
  {
    declare("name", cli::String_typed(), cli::REQUIRED, "The name of the thing added");
    declare("path", cli::String_typed(), cli::REQUIRED, "The path to the thing added");
    declare("config", cli::String_typed(), cli::REQUIRED, "Path to a configuration file");
    declare("version", cli::String_typed(), cli::REQUIRED, "The version of the thing added");
    declare("flag", cli::Bool_typed(), cli::REQUIRED, "A mysterious flag");
  }

  bool run(const cli::Arguments& args) {
    std::cout << "Adding...\n";
    return true;
  }
};

struct Del_command : cli::Command {
  Del_command()
    : Command("del", "Remove something from something else")
  {
    declare("name", cli::String_typed(), cli::REQUIRED, "The name of the thing removed");
    declare("path", cli::String_typed(), cli::REQUIRED, "The path to the thing being removed");
    declare("config", cli::String_typed(), cli::REQUIRED, "Path to a configuration file");
  }

  bool run(const cli::Arguments& args) {
    std::cout << "Removing...\n";
    return true;
  }
};

int
main(int argc, char *argv[]) {
  bool success = true;
  // Create program options.
  cli::Parameters parms;
  parms.declare("flag, f", cli::Bool_typed(), cli::REQUIRED, "Just a flag");
  parms.declare("number", cli::Real_typed(), "42", "Just a number");
  parms.declare("name", cli::String_typed(), "some value", "The name of something");
  parms.declare("config", cli::String_typed(), cli::OPTIONAL, "The path to a configuration file");
  parms.declare("path", cli::String_typed(), "*default path*", "Path to something");
  parms.declare("version, v", cli::Real_typed(), cli::REQUIRED, "Version of something");

  // Create commands.
  cli::Commands cmds;
  cmds.declare<Add_command>();
  cmds.declare<Del_command>();

// ---------------- Parse global arguments up to the command ---------------- //
  // Initialize the parse state
  cli::Parse_state ps(argc, 0, argv);

  // Initialize the program arguments
  cli::Arguments program_args;

  // Parse the environment for program options
  const char* prefix = "flog";
  parse_env(parms, program_args, prefix);

  // Parse the command-line for program options up to the command
  parse_keyword_args(parms, program_args, ps);

  // Check program args
  success &= check_args(parms, program_args);

  // if (!success){
  //   program_args.display_errors(*cmd, prefix);
  // }
// -------------------------------------------------------------------------- //

// ---------- Parse the command and its named/positional arguments ---------- //
  // Make sure a command name was provided
  if (ps.current == ps.argc) {
    std::cerr << "error: a command must be provided\n";
    return -1;
  }

  // Make sure the command exists
  std::string cmd_name = ps.argv[ps.current];
  if (!cmds.count(cmd_name)) {
    std::cerr << "error: command not recognized\n";
    return -1;
  }

    // FIXME: If this returns null, it will crash.
  cli::Parameters command_parms = cmds.find(cmd_name)->second->parms();
  cli::Arguments command_args;
  // Parse command args
  parse_args(command_parms, command_args, ps);

  // Check command args
  success &= check_args(command_parms, command_args);

  // if (!success){
  //   program_args.display_errors(*cmd, prefix);
  // }

  return 0;
  // // Parse arguments.
  // cli::Arguments args;
  // if (parse(parms, cmds, args, argc, argv, "flog"))
  //   return 0;
  // else
  //   return -1;

  // What command did I parse?
}
<commit_msg>worked on error handling for parsing<commit_after>// Copyright (c) 2013-2014 Flowgrammable.org
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an "AS IS"
// BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing
// permissions and limitations under the License.

#include <assert.h>

#include <freeflow/sys/socket.hpp>
#include <freeflow/sys/json.hpp>
#include <freeflow/sys/cli.hpp>

#include "command.hpp"

using namespace std;
using namespace freeflow;

struct Add_command : cli::Command {
  Add_command()
    : Command("add", "Add something to something else")
  {
    declare("name", cli::String_typed(), cli::REQUIRED, "The name of the thing added");
    declare("path", cli::String_typed(), cli::REQUIRED, "The path to the thing added");
    declare("config", cli::String_typed(), cli::REQUIRED, "Path to a configuration file");
    declare("version", cli::String_typed(), cli::REQUIRED, "The version of the thing added");
    declare("flag", cli::Bool_typed(), cli::REQUIRED, "A mysterious flag");
  }

  bool run(const cli::Arguments& args) {
    std::cout << "Adding...\n";
    return true;
  }
};

struct Del_command : cli::Command {
  Del_command()
    : Command("del", "Remove something from something else")
  {
    declare("name", cli::String_typed(), cli::REQUIRED, "The name of the thing removed");
    declare("path", cli::String_typed(), cli::REQUIRED, "The path to the thing being removed");
    declare("config", cli::String_typed(), cli::REQUIRED, "Path to a configuration file");
  }

  bool run(const cli::Arguments& args) {
    std::cout << "Removing...\n";
    return true;
  }
};

int
main(int argc, char *argv[]) {
  bool success = true;
  // Create program options.
  cli::Parameters parms;
  parms.declare("flag, f", cli::Bool_typed(), cli::REQUIRED, "Just a flag");
  parms.declare("number", cli::Real_typed(), "42", "Just a number");
  parms.declare("name", cli::String_typed(), "some value", "The name of something");
  parms.declare("config", cli::String_typed(), cli::OPTIONAL, "The path to a configuration file");
  parms.declare("path", cli::String_typed(), "*default path*", "Path to something");
  parms.declare("version, v", cli::Real_typed(), cli::REQUIRED, "Version of something");

  // Create commands.
  cli::Commands cmds;
  cmds.declare<Add_command>();
  cmds.declare<Del_command>();

// ---------------- Parse global arguments up to the command ---------------- //
  // Initialize the parse state
  cli::Parse_state ps(argc, 1, argv);
  if (ps.argc == 1) {
    std::cerr << "error: a command must be provided\n";
    return -1;
  }

  // Initialize the program arguments
  cli::Arguments program_args;

  // Parse the environment for program options
  const char* prefix = "flog";
  parse_env(parms, program_args, prefix);

  // Parse the command-line for program options up to the command
  parse_keyword_args(parms, program_args, ps);

  // Check program args
  success &= check_args(parms, program_args);

  // if (!success){
  //   program_args.display_errors(*cmd, prefix);
  // }
// -------------------------------------------------------------------------- //

// ---------- Parse the command and its named/positional arguments ---------- //
  // Make sure a command name was provided
  if (ps.current == ps.argc) {
    std::cerr << "error: a command must be provided\n";
    return -1;
  }

  // Make sure the command exists
  std::string cmd_name = ps.argv[ps.current];
  cout << cmd_name << endl;
  if (!cmds.count(cmd_name)) {
    std::cerr << "error: command not recognized\n";
    return -1;
  }

    // FIXME: If this returns null, it will crash.
  cli::Command* cmd = cmds.find(cmd_name)->second;
  cli::Arguments command_args;
  // Parse command args
  parse_args(cmd->parms(), command_args, ps);

  // Check command args
  success &= check_args(cmd->parms(), command_args);

  if (!success){
    //program_args.display_errors(*cmd, prefix);
    std::cout << "ERROR\n";
    return -1;
  }

  cmd->run(command_args);
  return 0;
  // // Parse arguments.
  // cli::Arguments args;
  // if (parse(parms, cmds, args, argc, argv, "flog"))
  //   return 0;
  // else
  //   return -1;

  // What command did I parse?
}
<|endoftext|>


<commit_before>#include "FactorizationTest.h"
#include "Utilities.h"
#include "common/SchedulerFactory.h"
#include "elves/common-factorization/BigInt.h"
#include "elves/quadratic_sieve/QuadraticSieve.h"
#include "elves/quadratic_sieve/smp/SmpQuadraticSieveElf.h"
#include "elves/quadratic_sieve/cuda/CudaQuadraticSieveElf.h"

#include <memory>
#include <vector>
#include <algorithm>
#include <chrono>

using namespace std;
using namespace chrono;

typedef vector<uint64_t> PrimeList;

const PrimeList SMALL_PRIMES = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
const PrimeList PRIMES_BELOW_100 = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

INSTANTIATE_TEST_CASE_P(
    PrimePairs,
    FactorizationTest,
    testing::Values(
        //make_pair(BigInt("37975227936943673922808872755445627854565536638199"),
        //          BigInt("40094690950920881030683735292761468389214899724061"))
        //make_pair(BigInt("9499938415355683567"), BigInt("33172199367355317419")),
        make_pair(BigInt("551226983117"), BigInt("554724632351")),
        make_pair(BigInt("15485863"), BigInt("15534733")),
        make_pair(BigInt("1313839"), BigInt("1327901")),
        make_pair(BigInt("547"), BigInt("719")),
    	make_pair(BigInt("13"), BigInt("11"))
    )
);

void FactorizationTest::SetUp()
{
    auto inputPair = GetParam();
    p = inputPair.first;
    q = inputPair.second;
    product = p*q;
}

TEST_P(FactorizationTest, testFactorizationQuadraticSieve)
{
    using namespace std::placeholders;
    auto start = high_resolution_clock::now();

    unique_ptr<QuadraticSieveElf> elf(new SmpQuadraticSieveElf());
    BigInt actualP, actualQ;
    tie(actualP, actualQ) = QuadraticSieveHelper::factor(product, bind(&QuadraticSieveElf::sieveSmoothSquares, elf.get(), _1, _2, _3, _4));

    auto end = high_resolution_clock::now();
    milliseconds elapsed = duration_cast<milliseconds>(end - start);
    std::cout << "total time: " << elapsed.count() / 1000.0 << " seconds" << endl;

    if(actualP > actualQ)
        swap(actualP, actualQ);

    ASSERT_EQ(p, actualP);
    ASSERT_EQ(q, actualQ);
}

#if 0
TEST_P(FactorizationTest, testFactorizationCudaQuadraticSieve)
{
    using namespace std::placeholders;
    auto start = high_resolution_clock::now();

    unique_ptr<QuadraticSieveElf> elf(new CudaQuadraticSieveElf());
    BigInt actualP, actualQ;
    tie(actualP, actualQ) = QuadraticSieveHelper::factor(product, bind(&QuadraticSieveElf::sieveSmoothSquares, elf.get(), _1, _2, _3, _4));

    auto end = high_resolution_clock::now();
    milliseconds elapsed = duration_cast<milliseconds>(end - start);
    std::cout << "total time: " << elapsed.count() / 1000.0 << " seconds" << endl;

    if(actualP > actualQ)
        swap(actualP, actualQ);

    ASSERT_EQ(p, actualP);
    ASSERT_EQ(q, actualQ);
}
#endif

TEST(QuadraticSieveTest, testModularSquareRoot)
{
    BigInt primeMod("104729");

    vector<string> roots = {"2", "12321", "4563", "34513", "13", "567856", "103729"};

    for(const string& rootstring : roots)
    {
        BigInt expectedRoot(rootstring);
        BigInt n = (expectedRoot*expectedRoot) % primeMod;
        BigInt root = QuadraticSieveHelper::rootModPrime(n, primeMod);
        ASSERT_NE(0, root);
        ASSERT_EQ(n, (root*root)%primeMod);
    }
}

TEST(QuadraticSieveTest, testModularSquareRoot2)
{
    BigInt primeMod("2909");

    vector<string> roots = {"305779185551528709018067"};

    for(const string& rootstring : roots)
    {
        BigInt expectedRoot(rootstring);
        BigInt n = (expectedRoot*expectedRoot) % primeMod;
        BigInt root = QuadraticSieveHelper::rootModPrime(n, primeMod);
        ASSERT_NE(0, root);
        ASSERT_EQ(n, (root*root)%primeMod);
    }
}

TEST(QuadraticSieveTest, testModularSquareRootInvalid)
{
    BigInt primeMod("7");
    BigInt n("3");

    ASSERT_THROW(QuadraticSieveHelper::rootModPrime(n, primeMod), logic_error);
}

TEST(QuadraticSieveTest, testExtensiveSquareRooting)
{
    vector<string> primeStrings = {"2", "3", "5", "7", "11", "13", "71", "229", "541"};
    BigInt threshold("10000");

    BigInt primePower;
    for(const string& primeString : primeStrings)
    {
        BigInt prime(primeString);
        BigInt primePower = prime;
        for(uint32_t power=1; primePower < threshold; power++, primePower*=prime)
        {
            map<BigInt, vector<BigInt>> rootsPerResidue;
            for(BigInt x=0; x<primePower; ++x)
            {
                BigInt residue = (x*x) % primePower;
                rootsPerResidue[residue].push_back(x);
            }

            for (auto& rpr: rootsPerResidue) {
                const BigInt& residue = rpr.first;
                const vector<BigInt>& expectedRoots = rpr.second;

                auto actualRoots = QuadraticSieveHelper::squareRootsModPrimePower(
                                    residue, prime, power);
                sort(actualRoots.begin(), actualRoots.end());

                ASSERT_EQ(expectedRoots.size(), actualRoots.size()) << "Vectors x and y are of unequal length";
                for (size_t i = 0; i < actualRoots.size(); ++i) {
                  ASSERT_EQ(expectedRoots[i], actualRoots[i]) << "Vectors x and y differ at index " << i;
                }
            }
        }
    }
}
<commit_msg>Commented smallest prime<commit_after>#include "FactorizationTest.h"
#include "Utilities.h"
#include "common/SchedulerFactory.h"
#include "elves/common-factorization/BigInt.h"
#include "elves/quadratic_sieve/QuadraticSieve.h"
#include "elves/quadratic_sieve/smp/SmpQuadraticSieveElf.h"
#include "elves/quadratic_sieve/cuda/CudaQuadraticSieveElf.h"

#include <memory>
#include <vector>
#include <algorithm>
#include <chrono>

using namespace std;
using namespace chrono;

typedef vector<uint64_t> PrimeList;

const PrimeList SMALL_PRIMES = { 2, 3, 5, 7, 11, 13, 17, 19, 23 };
const PrimeList PRIMES_BELOW_100 = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 };

INSTANTIATE_TEST_CASE_P(
    PrimePairs,
    FactorizationTest,
    testing::Values(
        //make_pair(BigInt("37975227936943673922808872755445627854565536638199"),
        //          BigInt("40094690950920881030683735292761468389214899724061"))
        //make_pair(BigInt("9499938415355683567"), BigInt("33172199367355317419")),
        make_pair(BigInt("551226983117"), BigInt("554724632351")),
        make_pair(BigInt("15485863"), BigInt("15534733")),
        make_pair(BigInt("1313839"), BigInt("1327901")),
        make_pair(BigInt("547"), BigInt("719"))
    	//make_pair(BigInt("13"), BigInt("11")) // too small
    )
);

void FactorizationTest::SetUp()
{
    auto inputPair = GetParam();
    p = inputPair.first;
    q = inputPair.second;
    product = p*q;
}

TEST_P(FactorizationTest, testFactorizationQuadraticSieve)
{
    using namespace std::placeholders;
    auto start = high_resolution_clock::now();

    unique_ptr<QuadraticSieveElf> elf(new SmpQuadraticSieveElf());
    BigInt actualP, actualQ;
    tie(actualP, actualQ) = QuadraticSieveHelper::factor(product, bind(&QuadraticSieveElf::sieveSmoothSquares, elf.get(), _1, _2, _3, _4));

    auto end = high_resolution_clock::now();
    milliseconds elapsed = duration_cast<milliseconds>(end - start);
    std::cout << "total time: " << elapsed.count() / 1000.0 << " seconds" << endl;

    if(actualP > actualQ)
        swap(actualP, actualQ);

    ASSERT_EQ(p, actualP);
    ASSERT_EQ(q, actualQ);
}

#if 0
TEST_P(FactorizationTest, testFactorizationCudaQuadraticSieve)
{
    using namespace std::placeholders;
    auto start = high_resolution_clock::now();

    unique_ptr<QuadraticSieveElf> elf(new CudaQuadraticSieveElf());
    BigInt actualP, actualQ;
    tie(actualP, actualQ) = QuadraticSieveHelper::factor(product, bind(&QuadraticSieveElf::sieveSmoothSquares, elf.get(), _1, _2, _3, _4));

    auto end = high_resolution_clock::now();
    milliseconds elapsed = duration_cast<milliseconds>(end - start);
    std::cout << "total time: " << elapsed.count() / 1000.0 << " seconds" << endl;

    if(actualP > actualQ)
        swap(actualP, actualQ);

    ASSERT_EQ(p, actualP);
    ASSERT_EQ(q, actualQ);
}
#endif

TEST(QuadraticSieveTest, testModularSquareRoot)
{
    BigInt primeMod("104729");

    vector<string> roots = {"2", "12321", "4563", "34513", "13", "567856", "103729"};

    for(const string& rootstring : roots)
    {
        BigInt expectedRoot(rootstring);
        BigInt n = (expectedRoot*expectedRoot) % primeMod;
        BigInt root = QuadraticSieveHelper::rootModPrime(n, primeMod);
        ASSERT_NE(0, root);
        ASSERT_EQ(n, (root*root)%primeMod);
    }
}

TEST(QuadraticSieveTest, testModularSquareRoot2)
{
    BigInt primeMod("2909");

    vector<string> roots = {"305779185551528709018067"};

    for(const string& rootstring : roots)
    {
        BigInt expectedRoot(rootstring);
        BigInt n = (expectedRoot*expectedRoot) % primeMod;
        BigInt root = QuadraticSieveHelper::rootModPrime(n, primeMod);
        ASSERT_NE(0, root);
        ASSERT_EQ(n, (root*root)%primeMod);
    }
}

TEST(QuadraticSieveTest, testModularSquareRootInvalid)
{
    BigInt primeMod("7");
    BigInt n("3");

    ASSERT_THROW(QuadraticSieveHelper::rootModPrime(n, primeMod), logic_error);
}

TEST(QuadraticSieveTest, testExtensiveSquareRooting)
{
    vector<string> primeStrings = {"2", "3", "5", "7", "11", "13", "71", "229", "541"};
    BigInt threshold("10000");

    BigInt primePower;
    for(const string& primeString : primeStrings)
    {
        BigInt prime(primeString);
        BigInt primePower = prime;
        for(uint32_t power=1; primePower < threshold; power++, primePower*=prime)
        {
            map<BigInt, vector<BigInt>> rootsPerResidue;
            for(BigInt x=0; x<primePower; ++x)
            {
                BigInt residue = (x*x) % primePower;
                rootsPerResidue[residue].push_back(x);
            }

            for (auto& rpr: rootsPerResidue) {
                const BigInt& residue = rpr.first;
                const vector<BigInt>& expectedRoots = rpr.second;

                auto actualRoots = QuadraticSieveHelper::squareRootsModPrimePower(
                                    residue, prime, power);
                sort(actualRoots.begin(), actualRoots.end());

                ASSERT_EQ(expectedRoots.size(), actualRoots.size()) << "Vectors x and y are of unequal length";
                for (size_t i = 0; i < actualRoots.size(); ++i) {
                  ASSERT_EQ(expectedRoots[i], actualRoots[i]) << "Vectors x and y differ at index " << i;
                }
            }
        }
    }
}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
Version:   $Revision: 18127 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

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

#ifndef __mitkNrrdDiffusionImageReader_cpp
#define __mitkNrrdDiffusionImageReader_cpp

#include "mitkNrrdDiffusionImageReader.h"

#include "itkImageFileReader.h"
#include "itkMetaDataObject.h"
#include "itkNrrdImageIO.h"

namespace mitk
{

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::GenerateData()
  {

    // Since everything is completely read in GenerateOutputInformation() it is stored
    // in a cache variable. A timestamp is associated.
    // If the timestamp of the cache variable is newer than the MTime, we only need to
    // assign the cache variable to the DataObject.
    // Otherwise, the tree must be read again from the file and OuputInformation must
    // be updated!
    if ( ( ! m_OutputCache ) || ( this->GetMTime( ) > m_CacheTime.GetMTime( ) ) )
    {
      this->GenerateOutputInformation();
      itkWarningMacro("Cache regenerated!");
    }

    if (!m_OutputCache)
    {
      itkWarningMacro("Tree cache is empty!");
    }

    static_cast<OutputType*>(this->GetOutput())
      ->SetVectorImage(m_OutputCache->GetVectorImage());
    static_cast<OutputType*>(this->GetOutput())
      ->SetB_Value(m_OutputCache->GetB_Value());
    static_cast<OutputType*>(this->GetOutput())
      ->SetDirections(m_OutputCache->GetDirections());
    static_cast<OutputType*>(this->GetOutput())
      ->InitializeFromVectorImage();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>::GenerateOutputInformation()
  {
    typename OutputType::Pointer outputForCache = OutputType::New();
    if ( m_FileName == "")
    {
      throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename to be read is empty!");
    }
    else
    {
      try
      {
        const std::string& locale = "en_GB.UTF-8";
        char *currLocale = setlocale( LC_ALL, NULL );

        if ( locale.compare(currLocale)!=0 )
        {
          try
          {
            MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'";
            setlocale(LC_ALL, locale.c_str());
          }
          catch(...)
          {
            MITK_INFO << "Could not activate locale " << locale;
          }
        }

        itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
        typedef itk::ImageFileReader<ImageType> FileReaderType;
        typename FileReaderType::Pointer reader = FileReaderType::New();
        reader->SetImageIO(io);
        reader->SetFileName(this->m_FileName);
        reader->Update();

        typename ImageType::Pointer img = reader->GetOutput();

        itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
        std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
        std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
        std::string metaString;

        GradientDirectionType vect3d;
        m_DiffusionVectors = GradientDirectionContainerType::New();

        int numberOfImages = 0;
        int numberOfGradientImages = 0;
        bool readb0 = false;

        for (; itKey != imgMetaKeys.end(); itKey ++)
        {
          double x,y,z;

          itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
          if (itKey->find("DWMRI_gradient") != std::string::npos)
          {
            std::cout << *itKey << " ---> " << metaString << std::endl;
            sscanf(metaString.c_str(), "%lf %lf %lf\n", &x, &y, &z);
            MITK_INFO << "read values: " << x << "; " << y << "; " << z;
            vect3d[0] = x; vect3d[1] = y; vect3d[2] = z;
            m_DiffusionVectors->InsertElement( numberOfImages, vect3d );
            ++numberOfImages;
            // If the direction is 0.0, this is a reference image
            if (vect3d[0] < 0.1 &&
              vect3d[1] < 0.1 &&
              vect3d[2] < 0.1)
            {
              MITK_INFO << "Reference image found..";
              continue;
            }
            ++numberOfGradientImages;;
          }
          else if (itKey->find("DWMRI_b-value") != std::string::npos)
          {
            std::cout << *itKey << " ---> " << metaString << std::endl;
            readb0 = true;
            m_B_Value = atof(metaString.c_str());
          }
        }

        std::cout << "Number of gradient images: "
          << numberOfGradientImages
          << " and Number of reference images: "
          << numberOfImages - numberOfGradientImages
          << std::endl;

        if(!readb0)
        {
          std::cerr << "BValue not specified in header file" << std::endl;
        }

        // This call updates the output information of the associated VesselTreeData
        outputForCache->SetVectorImage(img);
        outputForCache->SetB_Value(m_B_Value);
        outputForCache->SetDirections(m_DiffusionVectors);

        // Since we have already read the tree, we can store it in a cache variable
        // so that it can be assigned to the DataObject in GenerateData();
        m_OutputCache = outputForCache;
        m_CacheTime.Modified();
      }
      catch(std::exception& e)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
      }
      catch(...)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!");
      }
    }
  }

  template <class TPixelType>
  const char* NrrdDiffusionImageReader<TPixelType>
    ::GetFileName() const
  {
    return m_FileName.c_str();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::SetFileName(const char* aFileName)
  {
    m_FileName = aFileName;
  }

  template <class TPixelType>
  const char* NrrdDiffusionImageReader<TPixelType>
    ::GetFilePrefix() const
  {
    return m_FilePrefix.c_str();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::SetFilePrefix(const char* aFilePrefix)
  {
    m_FilePrefix = aFilePrefix;
  }

  template <class TPixelType>
  const char* NrrdDiffusionImageReader<TPixelType>
    ::GetFilePattern() const
  {
    return m_FilePattern.c_str();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::SetFilePattern(const char* aFilePattern)
  {
    m_FilePattern = aFilePattern;
  }

  template <class TPixelType>
  bool NrrdDiffusionImageReader<TPixelType>
    ::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
  {
    // First check the extension
    if(  filename == "" )
    {
      return false;
    }
    std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename);
    ext = itksys::SystemTools::LowerCase(ext);

    if (ext == ".hdwi" || ext == ".dwi")
    {
      itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();

      typedef itk::ImageFileReader<ImageType> FileReaderType;
      typename FileReaderType::Pointer reader = FileReaderType::New();
      reader->SetImageIO(io);
      reader->SetFileName(filename);
      reader->Update();
      typename ImageType::Pointer img = reader->GetOutput();
      itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
      std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
      std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
      std::string metaString;

      for (; itKey != imgMetaKeys.end(); itKey ++)
      {
        itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
        if (itKey->find("modality") != std::string::npos)
        {
          if (metaString.find("DWMRI") != std::string::npos)
          {
            return true;
          }
        }
      }
    }
    return false;
  }

} //namespace MITK

#endif
<commit_msg>FIX (#6271): fixed previous fix. comparison to 0 for reference image determination.<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2009-07-14 19:11:20 +0200 (Tue, 14 Jul 2009) $
Version:   $Revision: 18127 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

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

#ifndef __mitkNrrdDiffusionImageReader_cpp
#define __mitkNrrdDiffusionImageReader_cpp

#include "mitkNrrdDiffusionImageReader.h"

#include "itkImageFileReader.h"
#include "itkMetaDataObject.h"
#include "itkNrrdImageIO.h"

namespace mitk
{

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::GenerateData()
  {

    // Since everything is completely read in GenerateOutputInformation() it is stored
    // in a cache variable. A timestamp is associated.
    // If the timestamp of the cache variable is newer than the MTime, we only need to
    // assign the cache variable to the DataObject.
    // Otherwise, the tree must be read again from the file and OuputInformation must
    // be updated!
    if ( ( ! m_OutputCache ) || ( this->GetMTime( ) > m_CacheTime.GetMTime( ) ) )
    {
      this->GenerateOutputInformation();
      itkWarningMacro("Cache regenerated!");
    }

    if (!m_OutputCache)
    {
      itkWarningMacro("Tree cache is empty!");
    }

    static_cast<OutputType*>(this->GetOutput())
      ->SetVectorImage(m_OutputCache->GetVectorImage());
    static_cast<OutputType*>(this->GetOutput())
      ->SetB_Value(m_OutputCache->GetB_Value());
    static_cast<OutputType*>(this->GetOutput())
      ->SetDirections(m_OutputCache->GetDirections());
    static_cast<OutputType*>(this->GetOutput())
      ->InitializeFromVectorImage();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>::GenerateOutputInformation()
  {
    typename OutputType::Pointer outputForCache = OutputType::New();
    if ( m_FileName == "")
    {
      throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename to be read is empty!");
    }
    else
    {
      try
      {
        const std::string& locale = "en_GB.UTF-8";
        char *currLocale = setlocale( LC_ALL, NULL );

        if ( locale.compare(currLocale)!=0 )
        {
          try
          {
            MITK_INFO << " ** Changing locale from " << setlocale(LC_ALL, NULL) << " to '" << locale << "'";
            setlocale(LC_ALL, locale.c_str());
          }
          catch(...)
          {
            MITK_INFO << "Could not activate locale " << locale;
          }
        }

        itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();
        typedef itk::ImageFileReader<ImageType> FileReaderType;
        typename FileReaderType::Pointer reader = FileReaderType::New();
        reader->SetImageIO(io);
        reader->SetFileName(this->m_FileName);
        reader->Update();

        typename ImageType::Pointer img = reader->GetOutput();

        itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
        std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
        std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
        std::string metaString;

        GradientDirectionType vect3d;
        m_DiffusionVectors = GradientDirectionContainerType::New();

        int numberOfImages = 0;
        int numberOfGradientImages = 0;
        bool readb0 = false;

        for (; itKey != imgMetaKeys.end(); itKey ++)
        {
          double x,y,z;

          itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
          if (itKey->find("DWMRI_gradient") != std::string::npos)
          {
            std::cout << *itKey << " ---> " << metaString << std::endl;
            sscanf(metaString.c_str(), "%lf %lf %lf\n", &x, &y, &z);
            MITK_INFO << "read values: " << x << "; " << y << "; " << z;
            vect3d[0] = x; vect3d[1] = y; vect3d[2] = z;
            m_DiffusionVectors->InsertElement( numberOfImages, vect3d );
            ++numberOfImages;
            // If the direction is 0.0, this is a reference image
            if (vect3d[0] == 0.0 &&
              vect3d[1] == 0.0 &&
              vect3d[2] == 0.0)
            {
              MITK_INFO << "Reference image found..";
              continue;
            }
            ++numberOfGradientImages;;
          }
          else if (itKey->find("DWMRI_b-value") != std::string::npos)
          {
            std::cout << *itKey << " ---> " << metaString << std::endl;
            readb0 = true;
            m_B_Value = atof(metaString.c_str());
          }
        }

        std::cout << "Number of gradient images: "
          << numberOfGradientImages
          << " and Number of reference images: "
          << numberOfImages - numberOfGradientImages
          << std::endl;

        if(!readb0)
        {
          std::cerr << "BValue not specified in header file" << std::endl;
        }

        // This call updates the output information of the associated VesselTreeData
        outputForCache->SetVectorImage(img);
        outputForCache->SetB_Value(m_B_Value);
        outputForCache->SetDirections(m_DiffusionVectors);

        // Since we have already read the tree, we can store it in a cache variable
        // so that it can be assigned to the DataObject in GenerateData();
        m_OutputCache = outputForCache;
        m_CacheTime.Modified();
      }
      catch(std::exception& e)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
      }
      catch(...)
      {
        throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!");
      }
    }
  }

  template <class TPixelType>
  const char* NrrdDiffusionImageReader<TPixelType>
    ::GetFileName() const
  {
    return m_FileName.c_str();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::SetFileName(const char* aFileName)
  {
    m_FileName = aFileName;
  }

  template <class TPixelType>
  const char* NrrdDiffusionImageReader<TPixelType>
    ::GetFilePrefix() const
  {
    return m_FilePrefix.c_str();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::SetFilePrefix(const char* aFilePrefix)
  {
    m_FilePrefix = aFilePrefix;
  }

  template <class TPixelType>
  const char* NrrdDiffusionImageReader<TPixelType>
    ::GetFilePattern() const
  {
    return m_FilePattern.c_str();
  }

  template <class TPixelType>
  void NrrdDiffusionImageReader<TPixelType>
    ::SetFilePattern(const char* aFilePattern)
  {
    m_FilePattern = aFilePattern;
  }

  template <class TPixelType>
  bool NrrdDiffusionImageReader<TPixelType>
    ::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/)
  {
    // First check the extension
    if(  filename == "" )
    {
      return false;
    }
    std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename);
    ext = itksys::SystemTools::LowerCase(ext);

    if (ext == ".hdwi" || ext == ".dwi")
    {
      itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New();

      typedef itk::ImageFileReader<ImageType> FileReaderType;
      typename FileReaderType::Pointer reader = FileReaderType::New();
      reader->SetImageIO(io);
      reader->SetFileName(filename);
      reader->Update();
      typename ImageType::Pointer img = reader->GetOutput();
      itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary();
      std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
      std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
      std::string metaString;

      for (; itKey != imgMetaKeys.end(); itKey ++)
      {
        itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
        if (itKey->find("modality") != std::string::npos)
        {
          if (metaString.find("DWMRI") != std::string::npos)
          {
            return true;
          }
        }
      }
    }
    return false;
  }

} //namespace MITK

#endif
<|endoftext|>


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

 medInria

 Copyright (c) INRIA 2013. All rights reserved.
 See LICENSE.txt for details.

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

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

#include <medTabbedViewContainers.h>

#include <QUuid>
#include <QtCore>
#include <QShortcut>

#include <medViewContainer.h>
#include <medViewContainerSplitter.h>
#include <medViewContainerManager.h>

class medTabbedViewContainersPrivate
{
public:
    QShortcut *closeShortcut;
    QPushButton *addTabButton;
};

medTabbedViewContainers::medTabbedViewContainers(QWidget *parent) : QTabWidget(parent), d(new medTabbedViewContainersPrivate)
{
    this->setTabsClosable(true);
    this->setMovable(true);

    connect(this,SIGNAL(tabCloseRequested(int)),this,SLOT(resetTab(int)));

    d->addTabButton = new QPushButton(this);
    d->addTabButton->setObjectName("addTabButton");
    d->addTabButton->setShortcut(Qt::ControlModifier + Qt::Key_T);
    this->setCornerWidget(d->addTabButton);

    connect(d->addTabButton,SIGNAL(clicked()), this, SLOT(addContainerInTab()));

    d->closeShortcut = new QShortcut(this);
    d->closeShortcut->setKey(Qt::ControlModifier + Qt::Key_W);
    connect(d->closeShortcut,SIGNAL(activated()),this,SLOT(resetCurrentTab()));

    connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(disconnectTabFromSplitter(int)));
}

medTabbedViewContainers::~medTabbedViewContainers(void)
{
    delete d;
    d = NULL;
}

void medTabbedViewContainers::lockTabs()
{
    this->setTabsClosable(false);
    this->setMovable(false);
    d->addTabButton->hide();
}

void medTabbedViewContainers::unlockTabs()
{
    this->setTabsClosable(true);
    this->setMovable(true);
    d->addTabButton->show();
}

void medTabbedViewContainers::resetCurrentTab()
{
    int index = this->currentIndex();
    this->resetTab(index);
}

void medTabbedViewContainers::resetTab(int index)
{
    this->removeTab(index);
    if(this->count() < 1)
        this->addContainerInTab();
}

void medTabbedViewContainers::addContainerInTab()
{
    this->addContainerInTab("TODO find fancy name - RDE");
}

void medTabbedViewContainers::addContainerInTab(const QString &name)
{
    this->insertContainerInTab(this->count(), name);
}

void medTabbedViewContainers::insertContainerInTab(int index, const QString &name)
{
    medViewContainerSplitter *splitter  = new medViewContainerSplitter;
    int test = this->insertTab(index, splitter, name);
    this->setCurrentWidget(splitter);
//    this->setCurrentIndex(test);
    connect(splitter, SIGNAL(destroyed()), this, SLOT(repopulateCurrentTab()));
    connect(splitter, SIGNAL(newContainer(QUuid&)), this, SIGNAL(newContainer(QUuid&)));
    connect(splitter, SIGNAL(newContainer(QUuid&)), this, SLOT(addContainerToContainerInTab(QUuid&)));
    splitter->addViewContainer(new medViewContainer);
}

void medTabbedViewContainers::hideTabBar()
{
    QTabBar *tabBar = this->tabBar();
    tabBar->hide();
}

void medTabbedViewContainers::repopulateCurrentTab()
{
    int idx = this->currentIndex();
    qDebug()<< "idx" << idx;
    this->insertContainerInTab(idx, this->tabText(idx));
    qDebug()<< "this->currentIndex()" << this->currentIndex();
}

void medTabbedViewContainers::disconnectTabFromSplitter(int index)
{
    medViewContainerSplitter* splitter = dynamic_cast<medViewContainerSplitter*>(this->sender());
    if(!splitter)
        return;

    splitter->disconnect(this);
}

<commit_msg>correction in medTabbedViewContainers::repopulateCurrentTab<commit_after>/*=========================================================================

 medInria

 Copyright (c) INRIA 2013. All rights reserved.
 See LICENSE.txt for details.

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

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

#include <medTabbedViewContainers.h>

#include <QUuid>
#include <QtCore>
#include <QShortcut>

#include <medViewContainer.h>
#include <medViewContainerSplitter.h>
#include <medViewContainerManager.h>

class medTabbedViewContainersPrivate
{
public:
    QShortcut *closeShortcut;
    QPushButton *addTabButton;
};

medTabbedViewContainers::medTabbedViewContainers(QWidget *parent) : QTabWidget(parent), d(new medTabbedViewContainersPrivate)
{
    this->setTabsClosable(true);
    this->setMovable(true);

    connect(this,SIGNAL(tabCloseRequested(int)),this,SLOT(resetTab(int)));

    d->addTabButton = new QPushButton(this);
    d->addTabButton->setObjectName("addTabButton");
    d->addTabButton->setShortcut(Qt::ControlModifier + Qt::Key_T);
    this->setCornerWidget(d->addTabButton);

    connect(d->addTabButton,SIGNAL(clicked()), this, SLOT(addContainerInTab()));

    d->closeShortcut = new QShortcut(this);
    d->closeShortcut->setKey(Qt::ControlModifier + Qt::Key_W);
    connect(d->closeShortcut,SIGNAL(activated()),this,SLOT(resetCurrentTab()));

    connect(this, SIGNAL(tabCloseRequested(int)), this, SLOT(disconnectTabFromSplitter(int)));
}

medTabbedViewContainers::~medTabbedViewContainers(void)
{
    delete d;
    d = NULL;
}

void medTabbedViewContainers::lockTabs()
{
    this->setTabsClosable(false);
    this->setMovable(false);
    d->addTabButton->hide();
}

void medTabbedViewContainers::unlockTabs()
{
    this->setTabsClosable(true);
    this->setMovable(true);
    d->addTabButton->show();
}

void medTabbedViewContainers::resetCurrentTab()
{
    int index = this->currentIndex();
    this->resetTab(index);
}

void medTabbedViewContainers::resetTab(int index)
{
    this->removeTab(index);
    if(this->count() < 1)
        this->addContainerInTab();
}

void medTabbedViewContainers::addContainerInTab()
{
    this->addContainerInTab("TODO find fancy name - RDE");
}

void medTabbedViewContainers::addContainerInTab(const QString &name)
{
    this->insertContainerInTab(this->count(), name);
}

void medTabbedViewContainers::insertContainerInTab(int index, const QString &name)
{
    medViewContainerSplitter *splitter  = new medViewContainerSplitter;
    int idx = this->insertTab(index, splitter, name);
    this->setCurrentIndex(idx);
    connect(splitter, SIGNAL(destroyed()), this, SLOT(repopulateCurrentTab()));
    connect(splitter, SIGNAL(newContainer(QUuid&)), this, SIGNAL(newContainer(QUuid&)));
    connect(splitter, SIGNAL(newContainer(QUuid&)), this, SLOT(addContainerToContainerInTab(QUuid&)));
    splitter->addViewContainer(new medViewContainer);
}

void medTabbedViewContainers::hideTabBar()
{
    QTabBar *tabBar = this->tabBar();
    tabBar->hide();
}

void medTabbedViewContainers::repopulateCurrentTab()
{
    int idx = this->currentIndex();
    QString tabText = this->tabText(idx);
    this->removeTab(idx);
    this->insertContainerInTab(idx, tabText);
}

void medTabbedViewContainers::disconnectTabFromSplitter(int index)
{
    medViewContainerSplitter* splitter = dynamic_cast<medViewContainerSplitter*>(this->sender());
    if(!splitter)
        return;

    splitter->disconnect(this);
}

<|endoftext|>