<commit_before>#pragma once

#include <eosio/chain/action.hpp>
#include <eosio/chain/action_receipt.hpp>
#include <eosio/chain/block.hpp>

namespace eosio { namespace chain {

   struct account_delta {
      account_delta( const account_name& n, int64_t d):account(n),delta(d){}
      account_delta(){}

      account_name account;
      int64_t delta = 0;

      friend bool operator<( const account_delta& lhs, const account_delta& rhs ) { return lhs.account < rhs.account; }
   };

   struct transaction_trace;
   using transaction_trace_ptr = std::shared_ptr<transaction_trace>;

   struct action_trace {
      action_trace(  const transaction_trace& trace, const action& act, account_name receiver, bool context_free,
                     uint32_t action_ordinal, uint32_t creator_action_ordinal,
                     uint32_t closest_unnotified_ancestor_action_ordinal );
      action_trace(  const transaction_trace& trace, action&& act, account_name receiver, bool context_free,
                     uint32_t action_ordinal, uint32_t creator_action_ordinal,
                     uint32_t closest_unnotified_ancestor_action_ordinal );
      action_trace(){}

      fc::unsigned_int                action_ordinal;
      fc::unsigned_int                creator_action_ordinal;
      fc::unsigned_int                closest_unnotified_ancestor_action_ordinal;
      fc::optional<action_receipt>    receipt;
      action_name                     receiver;
      action                          act;
      bool                            context_free = false;
      fc::microseconds                elapsed;
      string                          console;
      transaction_id_type             trx_id; ///< the transaction that generated this action
      uint32_t                        block_num = 0;
      block_timestamp_type            block_time;
      fc::optional<block_id_type>     producer_block_id;
      flat_set<account_delta>         account_ram_deltas;
      fc::optional<fc::exception>     except;
      fc::optional<uint64_t>          error_code;
      std::vector<char>               return_value;
   };

   struct transaction_trace {
      transaction_id_type                        id;
      uint32_t                                   block_num = 0;
      block_timestamp_type                       block_time;
      fc::optional<block_id_type>                producer_block_id;
      fc::optional<transaction_receipt_header>   receipt;
      fc::microseconds                           elapsed;
      uint64_t                                   net_usage = 0;
      bool                                       scheduled = false;
      vector<action_trace>                       action_traces;
      fc::optional<account_delta>                account_ram_delta;

      transaction_trace_ptr                      failed_dtrx_trace;
      fc::optional<fc::exception>                except;
      fc::optional<uint64_t>                     error_code;
      std::exception_ptr                         except_ptr;
   };

   #define RAM_EVENT_ID( FORMAT, ... ) \
      fc::format_string( FORMAT, fc::mutable_variant_object()__VA_ARGS__ )

   struct ram_trace {
   public:
      ram_trace(uint32_t action_id, const char* event_id, const char* family, const char* operation, const char* legacy_tag)
      :action_id(action_id),event_id(event_id),family(family),operation(operation),legacy_tag(legacy_tag)
      {}

      uint32_t     action_id  = 0;
      const char*  event_id   = "generic";
      const char*  family     = "generic";
      const char*  operation  = "generic";
      const char*  legacy_tag = "generic";

   private:
      ram_trace(uint32_t action_id)
      :action_id(action_id)
      {}

      friend ram_trace generic_ram_trace(uint32_t);
   };

   inline ram_trace generic_ram_trace(uint32_t action_id) {
      return {action_id};
   }

   // struct ram_trace {
   // public:
   //    ram_trace(uint32_t action_id, const char* event_id, const char* family, const char* operation, const char* legacy_tag);

   //    inline uint32_t get_action_id() const { return action_id; }
   //    inline const char* get_event_id() const { return event_id; }
   //    inline const char* get_family() const { return family; }
   //    inline const char* get_operation() const { return operation; }
   //    inline const char* get_legacy_tag() const { return legacy_tag; }

   // protected:
   //    ram_trace();

   // private:
   //    uint32_t       action_id;
   //    const char*    event_id;
   //    const char*    family;
   //    const char*    operation;
   //    const char*    legacy_tag;
   // };

   // struct generic_ram_trace: public ram_trace {
   //    generic_ram_trace(): ram_trace() {}
   // };

} }  /// namespace eosio::chain

FC_REFLECT( eosio::chain::account_delta,
            (account)(delta) )

FC_REFLECT( eosio::chain::action_trace,
               (action_ordinal)(creator_action_ordinal)(closest_unnotified_ancestor_action_ordinal)(receipt)
               (receiver)(act)(context_free)(elapsed)(console)(trx_id)(block_num)(block_time)
               (producer_block_id)(account_ram_deltas)(except)(error_code)(return_value) )

FC_REFLECT( eosio::chain::transaction_trace, (id)(block_num)(block_time)(producer_block_id)
                                             (receipt)(elapsed)(net_usage)(scheduled)
                                             (action_traces)(account_ram_delta)(failed_dtrx_trace)(except)(error_code) )
<commit_msg>Removed left over commented code<commit_after>#pragma once

#include <eosio/chain/action.hpp>
#include <eosio/chain/action_receipt.hpp>
#include <eosio/chain/block.hpp>

namespace eosio { namespace chain {

   struct account_delta {
      account_delta( const account_name& n, int64_t d):account(n),delta(d){}
      account_delta(){}

      account_name account;
      int64_t delta = 0;

      friend bool operator<( const account_delta& lhs, const account_delta& rhs ) { return lhs.account < rhs.account; }
   };

   struct transaction_trace;
   using transaction_trace_ptr = std::shared_ptr<transaction_trace>;

   struct action_trace {
      action_trace(  const transaction_trace& trace, const action& act, account_name receiver, bool context_free,
                     uint32_t action_ordinal, uint32_t creator_action_ordinal,
                     uint32_t closest_unnotified_ancestor_action_ordinal );
      action_trace(  const transaction_trace& trace, action&& act, account_name receiver, bool context_free,
                     uint32_t action_ordinal, uint32_t creator_action_ordinal,
                     uint32_t closest_unnotified_ancestor_action_ordinal );
      action_trace(){}

      fc::unsigned_int                action_ordinal;
      fc::unsigned_int                creator_action_ordinal;
      fc::unsigned_int                closest_unnotified_ancestor_action_ordinal;
      fc::optional<action_receipt>    receipt;
      action_name                     receiver;
      action                          act;
      bool                            context_free = false;
      fc::microseconds                elapsed;
      string                          console;
      transaction_id_type             trx_id; ///< the transaction that generated this action
      uint32_t                        block_num = 0;
      block_timestamp_type            block_time;
      fc::optional<block_id_type>     producer_block_id;
      flat_set<account_delta>         account_ram_deltas;
      fc::optional<fc::exception>     except;
      fc::optional<uint64_t>          error_code;
      std::vector<char>               return_value;
   };

   struct transaction_trace {
      transaction_id_type                        id;
      uint32_t                                   block_num = 0;
      block_timestamp_type                       block_time;
      fc::optional<block_id_type>                producer_block_id;
      fc::optional<transaction_receipt_header>   receipt;
      fc::microseconds                           elapsed;
      uint64_t                                   net_usage = 0;
      bool                                       scheduled = false;
      vector<action_trace>                       action_traces;
      fc::optional<account_delta>                account_ram_delta;

      transaction_trace_ptr                      failed_dtrx_trace;
      fc::optional<fc::exception>                except;
      fc::optional<uint64_t>                     error_code;
      std::exception_ptr                         except_ptr;
   };

   #define RAM_EVENT_ID( FORMAT, ... ) \
      fc::format_string( FORMAT, fc::mutable_variant_object()__VA_ARGS__ )

   struct ram_trace {
   public:
      ram_trace(uint32_t action_id, const char* event_id, const char* family, const char* operation, const char* legacy_tag)
      :action_id(action_id),event_id(event_id),family(family),operation(operation),legacy_tag(legacy_tag)
      {}

      uint32_t     action_id  = 0;
      const char*  event_id   = "generic";
      const char*  family     = "generic";
      const char*  operation  = "generic";
      const char*  legacy_tag = "generic";

   private:
      ram_trace(uint32_t action_id)
      :action_id(action_id)
      {}

      friend ram_trace generic_ram_trace(uint32_t);
   };

   inline ram_trace generic_ram_trace(uint32_t action_id) {
      return {action_id};
   }

} }  /// namespace eosio::chain

FC_REFLECT( eosio::chain::account_delta,
            (account)(delta) )

FC_REFLECT( eosio::chain::action_trace,
               (action_ordinal)(creator_action_ordinal)(closest_unnotified_ancestor_action_ordinal)(receipt)
               (receiver)(act)(context_free)(elapsed)(console)(trx_id)(block_num)(block_time)
               (producer_block_id)(account_ram_deltas)(except)(error_code)(return_value) )

FC_REFLECT( eosio::chain::transaction_trace, (id)(block_num)(block_time)(producer_block_id)
                                             (receipt)(elapsed)(net_usage)(scheduled)
                                             (action_traces)(account_ram_delta)(failed_dtrx_trace)(except)(error_code) )
<|endoftext|>


<commit_before>#include <type/class.hh>

namespace type
{
    Class::Class(const std::string& name)
        : name_(name)
    {}

    Class::~Class()
    {}

    const std::string& Class::name_get() const
    {
        return name_;
    }

    ast::Ast* Class::component_get(const std::string& name)
    {
        return content_.at(name);
    }

    bool Class::component_add(const std::string& name, ast::Ast* dec)
    {
        // Component already exists
        if (!content_.at(name))
            return false;

        content_[name] = dec;

        return true;
    }

    std::ostream& Class::dump(std::ostream& o) const
    {
        o << "Class (" << name_ << ")";

        return o;
    }

    std::string Class::cpp_type() const
    {
        return name_ + "*";
    }
} // namespace type
<commit_msg>[TYPE] Correct unexpected throw on class type<commit_after>#include <type/class.hh>

namespace type
{
    Class::Class(const std::string& name)
        : name_(name)
    {}

    Class::~Class()
    {}

    const std::string& Class::name_get() const
    {
        return name_;
    }

    ast::Ast* Class::component_get(const std::string& name)
    {
        return content_[name];
    }

    bool Class::component_add(const std::string& name, ast::Ast* dec)
    {
        // Component already exists
        if (!content_[name])
            return false;

        content_[name] = dec;

        return true;
    }

    std::ostream& Class::dump(std::ostream& o) const
    {
        o << "Class (" << name_ << ")";

        return o;
    }

    std::string Class::cpp_type() const
    {
        return name_ + "*";
    }
} // namespace type
<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 * RLP tool.
 */
#include <fstream>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include "base64.h"
using namespace std;
using namespace dev;

void help()
{
	cout
		<< "Usage rlp [OPTIONS] [ <file> | -- ]" << endl
		<< "Options:" << endl
		<< "    -V,--version  Show the version and exit." << endl
		;
	exit(0);
}

void version()
{
	cout << "rlp version " << dev::Version << endl;
	exit(0);
}

enum class Mode {
	ListArchive,
	ExtractArchive,
	Render,
};

enum class Encoding {
	Auto,
	Hex,
	Base64,
	Binary,
};

bool isAscii(string const& _s)
{
	for (char c: _s)
		if (c < 32)
			return false;
	return true;
}

class RLPStreamer
{
public:
	struct Prefs
	{
		string indent = "  ";
		bool hexInts = false;
		bool forceString = false;
		bool escapeAll = false;
		bool forceHex = false;
	};

	RLPStreamer(ostream& _out, Prefs _p): m_out(_out), m_prefs(_p) {}

	void output(RLP const& _d, unsigned _level = 0)
	{
		if (_d.isNull())
			m_out << "null";
		else if (_d.isInt())
			if (m_prefs.hexInts)
				m_out << toHex(toCompactBigEndian(_d.toInt<bigint>(RLP::LaisezFaire)));
			else
				m_out << _d.toInt<bigint>(RLP::LaisezFaire);
		else if (_d.isData())
			if (m_prefs.forceString || (!m_prefs.forceHex && isAscii(_d.toString())))
				m_out << escaped(_d.toString(), m_prefs.escapeAll);
			else
				m_out << toHex(_d.data());
		else if (_d.isList())
		{
			m_out << "[";
			string newline = "\n";
			for (unsigned i = 0; i < _level + 1; ++i)
				newline += m_prefs.indent;
			int j = 0;
			for (auto i: _d)
			{
				m_out << (j++ ?
					(m_prefs.indent.empty() ? ", " : ("," + newline)) :
					(m_prefs.indent.empty() ? " " : newline));
				output(i, _level + 1);
			}
			newline = newline.substr(0, newline.size() - m_prefs.indent.size());
			m_out << (m_prefs.indent.empty() ? (j ? " ]" : "]") : (j ? newline + "]" : "]"));
		}
	}

private:
	std::ostream& m_out;
	Prefs m_prefs;
};

int main(int argc, char** argv)
{
	Encoding encoding = Encoding::Auto;
	Mode mode = Mode::Render;
	string inputFile = "--";
	bool lenience = false;
	RLPStreamer::Prefs prefs;

	for (int i = 1; i < argc; ++i)
	{
		string arg = argv[i];
		if (arg == "-h" || arg == "--help")
			help();
		else if (arg == "-r" || arg == "--render")
			mode = Mode::Render;
		else if ((arg == "-i" || arg == "--indent") && argc > i)
			prefs.indent = argv[++i];
		else if (arg == "--hex-ints")
			prefs.hexInts = true;
		else if (arg == "--force-string")
			prefs.forceString = true;
		else if (arg == "--force-hex")
			prefs.forceHex = true;
		else if (arg == "--force-escape")
			prefs.escapeAll = true;
		else if (arg == "-l" || arg == "--list-archive")
			mode = Mode::ListArchive;
		else if (arg == "-e" || arg == "--extract-archive")
			mode = Mode::ExtractArchive;
		else if (arg == "-L" || arg == "--lenience")
			lenience = true;
		else if (arg == "-V" || arg == "--version")
			version();
		else if (arg == "-x" || arg == "--hex" || arg == "--base-16")
			encoding = Encoding::Hex;
		else if (arg == "--64" || arg == "--base-64")
			encoding = Encoding::Base64;
		else if (arg == "-b" || arg == "--bin" || arg == "--base-256")
			encoding = Encoding::Binary;
		else
			inputFile = arg;
	}

	bytes in;
	if (inputFile == "--")
		for (int i = cin.get(); i != -1; i = cin.get())
			in.push_back((byte)i);
	else
		in = contents(inputFile);
	if (encoding == Encoding::Auto)
	{
		encoding = Encoding::Hex;
		for (char b: in)
			if (b != '\n' && b != ' ' && b != '\t')
			{
				if (encoding == Encoding::Hex && (b < '0' || b > '9' ) && (b < 'a' || b > 'f' ) && (b < 'A' || b > 'F' ))
				{
					cerr << "'" << b << "':" << (int)b << endl;
					encoding = Encoding::Base64;
				}
				if (encoding == Encoding::Base64 && (b < '0' || b > '9' ) && (b < 'a' || b > 'z' ) && (b < 'A' || b > 'Z' ) && b != '+' && b != '/')
				{
					encoding = Encoding::Binary;
					break;
				}
			}
	}
	bytes b;
	switch (encoding)
	{
	case Encoding::Hex:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = fromHex(s);
		break;
	}
	case Encoding::Base64:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = base64_decode(s);
		break;
	}
	default:
		swap(b, in);
		break;
	}

	try
	{
	RLP rlp(b);
	switch (mode)
	{
	case Mode::ListArchive:
	{
		if (!rlp.isList())
		{
			cout << "Error: Invalid format; RLP data is not a list." << endl;
			exit(1);
		}
		cout << rlp.itemCount() << " items:" << endl;
		for (auto i: rlp)
		{
			if (!i.isData())
			{
				cout << "Error: Invalid format; RLP list item is not data." << endl;
				if (!lenience)
					exit(1);
			}
			cout << "    " << i.size() << " bytes: " << sha3(i.data()) << endl;
		}
		break;
	}
	case Mode::ExtractArchive:
	{
		if (!rlp.isList())
		{
			cout << "Error: Invalid format; RLP data is not a list." << endl;
			exit(1);
		}
		cout << rlp.itemCount() << " items:" << endl;
		for (auto i: rlp)
		{
			if (!i.isData())
			{
				cout << "Error: Invalid format; RLP list item is not data." << endl;
				if (!lenience)
					exit(1);
			}
			ofstream fout;
			fout.open(toString(sha3(i.data())));
			fout.write(reinterpret_cast<char const*>(i.data().data()), i.data().size());
		}
		break;
	}
	case Mode::Render:
	{
		RLPStreamer s(cout, prefs);
		s.output(rlp);
		cout << endl;
		break;
	}
	default:;
	}
	}
	catch (...)
	{
		cerr << "Error: Invalid format; bad RLP." << endl;
		exit(1);
	}

	return 0;
}
<commit_msg>Improvements to help text of RLP.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 * RLP tool.
 */
#include <fstream>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include "base64.h"
using namespace std;
using namespace dev;

void help()
{
	cout
		<< "Usage rlp [OPTIONS] [ <file> | -- ]" << endl
		<< "Options:" << endl
		<< "    -r,--render  Render the given RLP. Options:" << endl
		<< "      --indent <string>  Use string as the level indentation (default '  ')." << endl
		<< "      --hex-ints  Render integers in hex." << endl
		<< "      --force-string  Force all data to be rendered as C-style strings." << endl
		<< "      --force-escape  When rendering as C-style strings, force all characters to be escaped." << endl
		<< "      --force-hex  Force all data to be rendered as raw hex." << endl
		<< "    -l,--list-archive  List the items in the RLP list by hash and size." << endl
		<< "    -e,--extract-archive  Extract all items in the RLP list, named by hash." << endl
		<< "General options:" << endl
		<< "    -L,--lenience  Try not to bomb out early if possible." << endl
		<< "    -x,--hex,--base-16  Treat input RLP as hex encoded data." << endl
		<< "    --64,--base-64  Treat input RLP as base-64 encoded data." << endl
		<< "    -b,--bin,--base-256  Treat input RLP as raw binary data." << endl
		<< "    -h,--help  Print this help message and exit." << endl
		<< "    -V,--version  Show the version and exit." << endl
		;
	exit(0);
}

void version()
{
	cout << "rlp version " << dev::Version << endl;
	exit(0);
}

enum class Mode {
	ListArchive,
	ExtractArchive,
	Render,
};

enum class Encoding {
	Auto,
	Hex,
	Base64,
	Binary,
};

bool isAscii(string const& _s)
{
	for (char c: _s)
		if (c < 32)
			return false;
	return true;
}

class RLPStreamer
{
public:
	struct Prefs
	{
		string indent = "  ";
		bool hexInts = false;
		bool forceString = false;
		bool escapeAll = false;
		bool forceHex = false;
	};

	RLPStreamer(ostream& _out, Prefs _p): m_out(_out), m_prefs(_p) {}

	void output(RLP const& _d, unsigned _level = 0)
	{
		if (_d.isNull())
			m_out << "null";
		else if (_d.isInt())
			if (m_prefs.hexInts)
				m_out << toHex(toCompactBigEndian(_d.toInt<bigint>(RLP::LaisezFaire), 1), 1);
			else
				m_out << _d.toInt<bigint>(RLP::LaisezFaire);
		else if (_d.isData())
			if (m_prefs.forceString || (!m_prefs.forceHex && isAscii(_d.toString())))
				m_out << escaped(_d.toString(), m_prefs.escapeAll);
			else
				m_out << toHex(_d.data());
		else if (_d.isList())
		{
			m_out << "[";
			string newline = "\n";
			for (unsigned i = 0; i < _level + 1; ++i)
				newline += m_prefs.indent;
			int j = 0;
			for (auto i: _d)
			{
				m_out << (j++ ?
					(m_prefs.indent.empty() ? ", " : ("," + newline)) :
					(m_prefs.indent.empty() ? " " : newline));
				output(i, _level + 1);
			}
			newline = newline.substr(0, newline.size() - m_prefs.indent.size());
			m_out << (m_prefs.indent.empty() ? (j ? " ]" : "]") : (j ? newline + "]" : "]"));
		}
	}

private:
	std::ostream& m_out;
	Prefs m_prefs;
};

int main(int argc, char** argv)
{
	Encoding encoding = Encoding::Auto;
	Mode mode = Mode::Render;
	string inputFile = "--";
	bool lenience = false;
	RLPStreamer::Prefs prefs;

	for (int i = 1; i < argc; ++i)
	{
		string arg = argv[i];
		if (arg == "-h" || arg == "--help")
			help();
		else if (arg == "-r" || arg == "--render")
			mode = Mode::Render;
		else if ((arg == "-i" || arg == "--indent") && argc > i)
			prefs.indent = argv[++i];
		else if (arg == "--hex-ints")
			prefs.hexInts = true;
		else if (arg == "--force-string")
			prefs.forceString = true;
		else if (arg == "--force-hex")
			prefs.forceHex = true;
		else if (arg == "--force-escape")
			prefs.escapeAll = true;
		else if (arg == "-l" || arg == "--list-archive")
			mode = Mode::ListArchive;
		else if (arg == "-e" || arg == "--extract-archive")
			mode = Mode::ExtractArchive;
		else if (arg == "-L" || arg == "--lenience")
			lenience = true;
		else if (arg == "-V" || arg == "--version")
			version();
		else if (arg == "-x" || arg == "--hex" || arg == "--base-16")
			encoding = Encoding::Hex;
		else if (arg == "--64" || arg == "--base-64")
			encoding = Encoding::Base64;
		else if (arg == "-b" || arg == "--bin" || arg == "--base-256")
			encoding = Encoding::Binary;
		else
			inputFile = arg;
	}

	bytes in;
	if (inputFile == "--")
		for (int i = cin.get(); i != -1; i = cin.get())
			in.push_back((byte)i);
	else
		in = contents(inputFile);
	if (encoding == Encoding::Auto)
	{
		encoding = Encoding::Hex;
		for (char b: in)
			if (b != '\n' && b != ' ' && b != '\t')
			{
				if (encoding == Encoding::Hex && (b < '0' || b > '9' ) && (b < 'a' || b > 'f' ) && (b < 'A' || b > 'F' ))
				{
					cerr << "'" << b << "':" << (int)b << endl;
					encoding = Encoding::Base64;
				}
				if (encoding == Encoding::Base64 && (b < '0' || b > '9' ) && (b < 'a' || b > 'z' ) && (b < 'A' || b > 'Z' ) && b != '+' && b != '/')
				{
					encoding = Encoding::Binary;
					break;
				}
			}
	}
	bytes b;
	switch (encoding)
	{
	case Encoding::Hex:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = fromHex(s);
		break;
	}
	case Encoding::Base64:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = base64_decode(s);
		break;
	}
	default:
		swap(b, in);
		break;
	}

	try
	{
	RLP rlp(b);
	switch (mode)
	{
	case Mode::ListArchive:
	{
		if (!rlp.isList())
		{
			cout << "Error: Invalid format; RLP data is not a list." << endl;
			exit(1);
		}
		cout << rlp.itemCount() << " items:" << endl;
		for (auto i: rlp)
		{
			if (!i.isData())
			{
				cout << "Error: Invalid format; RLP list item is not data." << endl;
				if (!lenience)
					exit(1);
			}
			cout << "    " << i.size() << " bytes: " << sha3(i.data()) << endl;
		}
		break;
	}
	case Mode::ExtractArchive:
	{
		if (!rlp.isList())
		{
			cout << "Error: Invalid format; RLP data is not a list." << endl;
			exit(1);
		}
		cout << rlp.itemCount() << " items:" << endl;
		for (auto i: rlp)
		{
			if (!i.isData())
			{
				cout << "Error: Invalid format; RLP list item is not data." << endl;
				if (!lenience)
					exit(1);
			}
			ofstream fout;
			fout.open(toString(sha3(i.data())));
			fout.write(reinterpret_cast<char const*>(i.data().data()), i.data().size());
		}
		break;
	}
	case Mode::Render:
	{
		RLPStreamer s(cout, prefs);
		s.output(rlp);
		cout << endl;
		break;
	}
	default:;
	}
	}
	catch (...)
	{
		cerr << "Error: Invalid format; bad RLP." << endl;
		exit(1);
	}

	return 0;
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "formeditorplugin.h"

#if QT_VERSION < 0x050000
#include <QtTest>
#else
#include "formeditorw.h"

#include <coreplugin/testdatadir.h>
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolseditorsupport.h>

#include <cplusplus/CppDocument.h>
#include <cplusplus/Overview.h>
#include <utils/fileutils.h>

#include <QDesignerFormEditorInterface>
#include <QDesignerIntegrationInterface>
#include <QStringList>
#include <QtTest>

using namespace Core;
using namespace Core::Internal::Tests;
using namespace CppTools;
using namespace CPlusPlus;
using namespace Designer;
using namespace Designer::Internal;

namespace {

class MyTestDataDir : public Core::Internal::Tests::TestDataDir {
public:
    MyTestDataDir(const QString &dir)
        : TestDataDir(QLatin1String(SRCDIR "/../../../tests/designer/") + dir)
    {}
};

QString expectedContentsForFile(const QString &filePath)
{
    QFileInfo fi(filePath);
    const QString referenceFileName = QLatin1String("reference_") + fi.fileName();
    const QString referenceFilePath = fi.dir().absoluteFilePath(referenceFileName);

    Utils::FileReader fileReader;
    const bool isFetchOk = fileReader.fetch(referenceFilePath);
    if (isFetchOk)
        return QString::fromUtf8(fileReader.data());
    return QString();
}

class GoToSlotTest
{
public:
    GoToSlotTest(const QStringList &files)
        : m_files(files)
        , m_modelManager(CppModelManagerInterface::instance())
    {
        QCOMPARE(files.size(), 3);
        cleanup();
    }
    ~GoToSlotTest() { cleanup(); }

    void run() const
    {
        QList<TextEditor::BaseTextEditor *> editors;
        foreach (const QString &file, m_files) {
            IEditor *editor = EditorManager::openEditor(file);
            TextEditor::BaseTextEditor *e = qobject_cast<TextEditor::BaseTextEditor *>(editor);
            QVERIFY(e);
            editors << e;
        }
        TextEditor::BaseTextEditor *cppFileEditor = editors.at(0);
        TextEditor::BaseTextEditor *hFileEditor = editors.at(1);

        const QString cppFile = m_files.at(0);
        const QString hFile = m_files.at(1);

        QCOMPARE(EditorManager::documentModel()->openedDocuments().size(), m_files.size());
        while (!m_modelManager->snapshot().contains(cppFile)
                 || !m_modelManager->snapshot().contains(hFile)) {
            QApplication::processEvents();
        }

        // Execute "Go To Slot"
        FormEditorW *few = FormEditorW::instance();
        QDesignerIntegrationInterface *integration = few->designerEditor()->integration();
        QVERIFY(integration);
        integration->emitNavigateToSlot(QLatin1String("pushButton"), QLatin1String("clicked()"),
                                        QStringList());

        QCOMPARE(EditorManager::currentDocument()->filePath(), cppFile);
        QVERIFY(EditorManager::currentDocument()->isModified());

        // Wait for updated documents
        foreach (TextEditor::BaseTextEditor *editor, editors) {
            if (CppEditorSupport *editorSupport = m_modelManager->cppEditorSupport(editor)) {
                while (editorSupport->isUpdatingDocument())
                    QApplication::processEvents();
            }
        }

        // Compare
        QCOMPARE(cppFileEditor->textDocument()->contents(), expectedContentsForFile(cppFile));
        QCOMPARE(hFileEditor->textDocument()->contents(), expectedContentsForFile(hFile));
    }

private:
    void cleanup()
    {
        EditorManager::closeAllEditors(/*askAboutModifiedEditors =*/ false);
        QVERIFY(EditorManager::documentModel()->openedDocuments().isEmpty());

        m_modelManager->GC();
        QVERIFY(m_modelManager->snapshot().isEmpty());
    }

private:
    QStringList m_files;
    CppModelManagerInterface *m_modelManager;
};

} // anonymous namespace
#endif

/// Check: Executes "Go To Slot..." on a QPushButton in a *.ui file and checks if the respective
/// header and source files are updated.
void Designer::Internal::FormEditorPlugin::test_gotoslot()
{
#if QT_VERSION >= 0x050000
    QFETCH(QStringList, files);

    GoToSlotTest test(files);
    test.run();
#else
    QSKIP("Available only with >= Qt5", SkipSingle);
#endif
}

void FormEditorPlugin::test_gotoslot_data()
{
    typedef QLatin1String _;
    QTest::addColumn<QStringList>("files");

    MyTestDataDir testData(QLatin1String("gotoslot_withoutProject"));
    QTest::newRow("withoutProject")
        << (QStringList()
            << testData.file(_("form.cpp"))
            << testData.file(_("form.h"))
            << testData.file(_("form.ui")));
}
<commit_msg>Designer: Tests: Fix compilation with Qt4<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "formeditorplugin.h"

#if QT_VERSION < 0x050000
#include <QtTest>
#else
#include "formeditorw.h"

#include <coreplugin/testdatadir.h>
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolseditorsupport.h>

#include <cplusplus/CppDocument.h>
#include <cplusplus/Overview.h>
#include <utils/fileutils.h>

#include <QDesignerFormEditorInterface>
#include <QDesignerIntegrationInterface>
#include <QStringList>
#include <QtTest>

using namespace Core;
using namespace Core::Internal::Tests;
using namespace CppTools;
using namespace CPlusPlus;
using namespace Designer;
using namespace Designer::Internal;

namespace {

class MyTestDataDir : public Core::Internal::Tests::TestDataDir {
public:
    MyTestDataDir(const QString &dir)
        : TestDataDir(QLatin1String(SRCDIR "/../../../tests/designer/") + dir)
    {}
};

QString expectedContentsForFile(const QString &filePath)
{
    QFileInfo fi(filePath);
    const QString referenceFileName = QLatin1String("reference_") + fi.fileName();
    const QString referenceFilePath = fi.dir().absoluteFilePath(referenceFileName);

    Utils::FileReader fileReader;
    const bool isFetchOk = fileReader.fetch(referenceFilePath);
    if (isFetchOk)
        return QString::fromUtf8(fileReader.data());
    return QString();
}

class GoToSlotTest
{
public:
    GoToSlotTest(const QStringList &files)
        : m_files(files)
        , m_modelManager(CppModelManagerInterface::instance())
    {
        QCOMPARE(files.size(), 3);
        cleanup();
    }
    ~GoToSlotTest() { cleanup(); }

    void run() const
    {
        QList<TextEditor::BaseTextEditor *> editors;
        foreach (const QString &file, m_files) {
            IEditor *editor = EditorManager::openEditor(file);
            TextEditor::BaseTextEditor *e = qobject_cast<TextEditor::BaseTextEditor *>(editor);
            QVERIFY(e);
            editors << e;
        }
        TextEditor::BaseTextEditor *cppFileEditor = editors.at(0);
        TextEditor::BaseTextEditor *hFileEditor = editors.at(1);

        const QString cppFile = m_files.at(0);
        const QString hFile = m_files.at(1);

        QCOMPARE(EditorManager::documentModel()->openedDocuments().size(), m_files.size());
        while (!m_modelManager->snapshot().contains(cppFile)
                 || !m_modelManager->snapshot().contains(hFile)) {
            QApplication::processEvents();
        }

        // Execute "Go To Slot"
        FormEditorW *few = FormEditorW::instance();
        QDesignerIntegrationInterface *integration = few->designerEditor()->integration();
        QVERIFY(integration);
        integration->emitNavigateToSlot(QLatin1String("pushButton"), QLatin1String("clicked()"),
                                        QStringList());

        QCOMPARE(EditorManager::currentDocument()->filePath(), cppFile);
        QVERIFY(EditorManager::currentDocument()->isModified());

        // Wait for updated documents
        foreach (TextEditor::BaseTextEditor *editor, editors) {
            if (CppEditorSupport *editorSupport = m_modelManager->cppEditorSupport(editor)) {
                while (editorSupport->isUpdatingDocument())
                    QApplication::processEvents();
            }
        }

        // Compare
        QCOMPARE(cppFileEditor->textDocument()->contents(), expectedContentsForFile(cppFile));
        QCOMPARE(hFileEditor->textDocument()->contents(), expectedContentsForFile(hFile));
    }

private:
    void cleanup()
    {
        EditorManager::closeAllEditors(/*askAboutModifiedEditors =*/ false);
        QVERIFY(EditorManager::documentModel()->openedDocuments().isEmpty());

        m_modelManager->GC();
        QVERIFY(m_modelManager->snapshot().isEmpty());
    }

private:
    QStringList m_files;
    CppModelManagerInterface *m_modelManager;
};

} // anonymous namespace
#endif

/// Check: Executes "Go To Slot..." on a QPushButton in a *.ui file and checks if the respective
/// header and source files are updated.
void Designer::Internal::FormEditorPlugin::test_gotoslot()
{
#if QT_VERSION >= 0x050000
    QFETCH(QStringList, files);

    GoToSlotTest test(files);
    test.run();
#else
    QSKIP("Available only with >= Qt5", SkipSingle);
#endif
}

void Designer::Internal::FormEditorPlugin::test_gotoslot_data()
{
#if QT_VERSION >= 0x050000
    typedef QLatin1String _;
    QTest::addColumn<QStringList>("files");

    MyTestDataDir testData(QLatin1String("gotoslot_withoutProject"));
    QTest::newRow("withoutProject")
        << (QStringList()
            << testData.file(_("form.cpp"))
            << testData.file(_("form.h"))
            << testData.file(_("form.ui")));
#endif
}
<|endoftext|>


<commit_before>/**@file Logical Channel.  */

/*
* Copyright 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
* Copyright 2011 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "GSML3RRElements.h"
#include "GSML3Message.h"
#include "GSML3RRMessages.h"
#include "GSMLogicalChannel.h"
#include "GSMConfig.h"

#include <TransactionTable.h>
#include <SMSControl.h>
#include <ControlCommon.h>

#include <Logger.h>
#undef WARNING

using namespace std;
using namespace GSM;

void LogicalChannel::open()
{
	LOG(INFO);
	if (mSACCH) mSACCH->open();
	if (mL1) mL1->open();
	for (int s=0; s<4; s++) {
		if (mL2[s]) mL2[s]->open();
	}
	// Empty any stray transactions in the FIFO from the SIP layer.
	while (true) {
		Control::TransactionEntry *trans = mTransactionFIFO.readNoBlock();
		if (!trans) break;
		LOG(WARNING) << "flushing stray transaction " << *trans;
	}
}

void LogicalChannel::connect()
{
	mMux.downstream(mL1);
	if (mL1) mL1->upstream(&mMux);
	for (int s=0; s<4; s++) {
		mMux.upstream(mL2[s],s);
		if (mL2[s]) mL2[s]->downstream(&mMux);
	}
}

void LogicalChannel::downstream(ARFCNManager* radio)
{
	assert(mL1);
	mL1->downstream(radio);
	if (mSACCH) mSACCH->downstream(radio);
}

// Serialize and send an L3Message with a given primitive.
void LogicalChannel::send(const L3Message& msg,
		const GSM::Primitive& prim,
		unsigned SAPI)
{
	LOG(INFO) << "L3 SAP" << SAPI << " sending " << msg;
	send(L3Frame(msg,prim), SAPI);
}

CCCHLogicalChannel::CCCHLogicalChannel(const TDMAMapping& wMapping)
	:mRunning(false)
{
	mL1 = new CCCHL1FEC(wMapping);
	mL2[0] = new CCCHL2;
	connect();
}

void CCCHLogicalChannel::open()
{
	LogicalChannel::open();
	if (!mRunning) {
		mRunning=true;
		mServiceThread.start((void*(*)(void*))CCCHLogicalChannelServiceLoopAdapter,this);
	}
}

void CCCHLogicalChannel::serviceLoop()
{
	// build the idle frame
	static const L3PagingRequestType1 filler;
	static const L3Frame idleFrame(filler,UNIT_DATA);
	// prime the first idle frame
	LogicalChannel::send(idleFrame);
	// run the loop
	while (true) {
		L3Frame* frame = mQ.read();
		if (frame) {
			LogicalChannel::send(*frame);
			OBJLOG(DEBUG) << "CCCHLogicalChannel::serviceLoop sending " << *frame;
			delete frame;
		}
		if (mQ.size()==0) {
			LogicalChannel::send(idleFrame);
			OBJLOG(DEBUG) << "CCCHLogicalChannel::serviceLoop sending idle frame";
		}
	}
}

void *GSM::CCCHLogicalChannelServiceLoopAdapter(CCCHLogicalChannel* chan)
{
	chan->serviceLoop();
	return NULL;
}

L3ChannelDescription LogicalChannel::channelDescription() const
{
	// In some debug cases, L1 may not exist, so we fake this information.
	if (mL1==NULL) return L3ChannelDescription(TDMA_MISC,0,0,0);

	// In normal cases, we get this information from L1.
	return L3ChannelDescription(
		mL1->typeAndOffset(),
		mL1->TN(),
		mL1->TSC(),
		mL1->ARFCN()
	);
}

SDCCHLogicalChannel::SDCCHLogicalChannel(
		unsigned wCN,
		unsigned wTN,
		const CompleteMapping& wMapping)
{
	mL1 = new SDCCHL1FEC(wCN,wTN,wMapping.LCH());
	// SAP0 is RR/MM/CC, SAP3 is SMS
	// SAP1 and SAP2 are not used.
	L2LAPDm *SAP0L2 = new SDCCHL2(1,0);
	L2LAPDm *SAP3L2 = new SDCCHL2(1,3);
	LOG(DEBUG) << "LAPDm pairs SAP0=" << SAP0L2 << " SAP3=" << SAP3L2;
	SAP3L2->master(SAP0L2);
	mL2[0] = SAP0L2;
	mL2[3] = SAP3L2;
	mSACCH = new SACCHLogicalChannel(wCN,wTN,wMapping.SACCH());
	connect();
}

SACCHLogicalChannel::SACCHLogicalChannel(
		unsigned wCN,
		unsigned wTN,
		const MappingPair& wMapping)
		: mRunning(false)
{
	mSACCHL1 = new SACCHL1FEC(wCN,wTN,wMapping);
	mL1 = mSACCHL1;
	// SAP0 is RR, SAP3 is SMS
	// SAP1 and SAP2 are not used.
	mL2[0] = new SACCHL2(1,0);
	mL2[3] = new SACCHL2(1,3);
	connect();
	assert(mSACCH==NULL);
}

void SACCHLogicalChannel::open()
{
	LogicalChannel::open();
	if (!mRunning) {
		mRunning=true;
		mServiceThread.start((void*(*)(void*))SACCHLogicalChannelServiceLoopAdapter,this);
	}
}

L3Message* processSACCHMessage(L3Frame *l3frame)
{
	if (!l3frame) return NULL;
	LOG(DEBUG) << *l3frame;
	Primitive prim = l3frame->primitive();
	if ((prim!=DATA) && (prim!=UNIT_DATA)) {
		LOG(INFO) << "non-data primitive " << prim;
		return NULL;
	}
	// FIXME -- Why, again, do we need to do this?
//	L3Frame realFrame = l3frame->segment(24, l3frame->size()-24);
	L3Message* message = parseL3(*l3frame);
	if (!message) {
		LOG(WARNING) << "SACCH recevied unparsable L3 frame " << *l3frame;
	}
	return message;
}

void SACCHLogicalChannel::serviceLoop()
{
	// run the loop
	unsigned count = 0;
	while (true) {

		// Throttle back if not active.
		if (!active()) {
			OBJLOG(DEBUG) << "SACCH sleeping";
			sleepFrames(51);
			continue;
		}

		// TODO SMS -- Check to see if the tx queues are empty.  If so, send SI5/6,
		// otherwise sleep and continue;

		// Send alternating SI5/SI6.
		OBJLOG(DEBUG) << "sending SI5/6 on SACCH";
		if (count%2) LogicalChannel::send(gBTS.SI5Frame());
		else LogicalChannel::send(gBTS.SI6Frame());
		count++;

		// Receive inbound messages.
		// This read loop flushes stray reports quickly.
		while (true) {

			OBJLOG(DEBUG) << "polling SACCH for inbound messages";
			bool nothing = true;

			// Process SAP0 -- RR Measurement reports
			L3Frame *rrFrame = LogicalChannel::recv(0,0);
			if (rrFrame) nothing=false;
			L3Message* rrMessage = processSACCHMessage(rrFrame);
			delete rrFrame;
			if (rrMessage) {
				L3MeasurementReport* measurement = dynamic_cast<L3MeasurementReport*>(rrMessage);
				if (measurement) {
					mMeasurementResults = measurement->results();
					OBJLOG(DEBUG) << "SACCH measurement report " << mMeasurementResults;
					// Add the measurement results to the table
					// Note that the typeAndOffset of a SACCH match the host channel.
					gPhysStatus.setPhysical(this, mMeasurementResults);
				} else {
					OBJLOG(NOTICE) << "SACCH SAP0 sent unaticipated message " << rrMessage;
				}
				delete rrMessage;
			}

			// Process SAP3 -- SMS
			L3Frame *smsFrame = LogicalChannel::recv(0,3);
			if (smsFrame) nothing=false;
			L3Message* smsMessage = processSACCHMessage(smsFrame);
			delete smsFrame;
			if (smsMessage) {
				const SMS::CPData* cpData = dynamic_cast<const SMS::CPData*>(smsMessage);
				if (cpData) {
					OBJLOG(INFO) << "SMS CPDU " << *cpData;
					Control::TransactionEntry *transaction = gTransactionTable.find(this);
					try {
						if (transaction) {
							Control::InCallMOSMSController(cpData,transaction,this);
						} else {
							OBJLOG(WARNING) << "in-call MOSMS CP-DATA with no corresponding transaction";
						}
					} catch (Control::ControlLayerException e) {
						//LogicalChannel::send(RELEASE,3);
						gTransactionTable.remove(e.transactionID());
					}
				} else {
					OBJLOG(NOTICE) << "SACCH SAP3 sent unaticipated message " << rrMessage;
				}
				delete smsMessage;
			}

			// Anything from the SIP side?
			// MTSMS (delivery from SIP to the MS)
			Control::TransactionEntry *sipTransaction = mTransactionFIFO.readNoBlock();
			if (sipTransaction) {
				OBJLOG(INFO) << "SIP-side transaction: " << sipTransaction;
				assert(sipTransaction->service() == L3CMServiceType::MobileTerminatedShortMessage);
				try {
					Control::MTSMSController(sipTransaction,this);
				} catch (Control::ControlLayerException e) {
					//LogicalChannel::send(RELEASE,3);
					gTransactionTable.remove(e.transactionID());
				}
			}

			// Nothing happened?
			if (nothing) break;
		}

	}
}

void *GSM::SACCHLogicalChannelServiceLoopAdapter(SACCHLogicalChannel* chan)
{
	chan->serviceLoop();
	return NULL;
}

// These have to go into the .cpp file to prevent an illegal forward reference.
void LogicalChannel::setPhy(float wRSSI, float wTimingError)
	{ assert(mSACCH); mSACCH->setPhy(wRSSI,wTimingError); }
void LogicalChannel::setPhy(const LogicalChannel& other)
	{ assert(mSACCH); mSACCH->setPhy(*other.SACCH()); }
float LogicalChannel::RSSI() const
	{ assert(mSACCH); return mSACCH->RSSI(); }
float LogicalChannel::timingError() const
	{ assert(mSACCH); return mSACCH->timingError(); }
int LogicalChannel::actualMSPower() const
	{ assert(mSACCH); return mSACCH->actualMSPower(); }
int LogicalChannel::actualMSTiming() const
	{ assert(mSACCH); return mSACCH->actualMSTiming(); }

TCHFACCHLogicalChannel::TCHFACCHLogicalChannel(
		unsigned wCN,
		unsigned wTN,
		const CompleteMapping& wMapping)
{
	mTCHL1 = new TCHFACCHL1FEC(wCN,wTN,wMapping.LCH());
	mL1 = mTCHL1;
	// SAP0 is RR/MM/CC, SAP3 is SMS
	// SAP1 and SAP2 are not used.
	mL2[0] = new FACCHL2(1,0);
	mL2[3] = new FACCHL2(1,3);
	mSACCH = new SACCHLogicalChannel(wCN,wTN,wMapping.SACCH());
	connect();
}

bool LogicalChannel::waitForPrimitive(Primitive primitive, unsigned timeout_ms)
{
	bool waiting = true;
	while (waiting) {
		L3Frame *req = recv(timeout_ms);
		if (req==NULL) {
			LOG(NOTICE) << "timeout at uptime " << gBTS.uptime() << " frame " << gBTS.time();
			return false;
		}
		waiting = (req->primitive()!=primitive);
		delete req;
	}
	return true;
}

void LogicalChannel::waitForPrimitive(Primitive primitive)
{
	bool waiting = true;
	while (waiting) {
		L3Frame *req = recv();
		if (req==NULL) continue;
		waiting = (req->primitive()!=primitive);
		delete req;
	}
}

ostream& GSM::operator<<(ostream& os, const LogicalChannel& chan)
{
	os << chan.descriptiveString();
	return os;
}

void LogicalChannel::addTransaction(Control::TransactionEntry *transaction)
{
	assert(transaction->channel()==this);
	mTransactionFIFO.write(transaction);
}

// vim: ts=4 sw=4

<commit_msg>r4226 in private: Added a comment pointing out a potential memory leak.<commit_after>/**@file Logical Channel.  */

/*
* Copyright 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
* Copyright 2011 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "GSML3RRElements.h"
#include "GSML3Message.h"
#include "GSML3RRMessages.h"
#include "GSMLogicalChannel.h"
#include "GSMConfig.h"

#include <TransactionTable.h>
#include <SMSControl.h>
#include <ControlCommon.h>

#include <Logger.h>
#undef WARNING

using namespace std;
using namespace GSM;

void LogicalChannel::open()
{
	LOG(INFO);
	if (mSACCH) mSACCH->open();
	if (mL1) mL1->open();
	for (int s=0; s<4; s++) {
		if (mL2[s]) mL2[s]->open();
	}
	// Empty any stray transactions in the FIFO from the SIP layer.
	while (true) {
		Control::TransactionEntry *trans = mTransactionFIFO.readNoBlock();
		if (!trans) break;
		LOG(WARNING) << "flushing stray transaction " << *trans;
		// FIXME -- Shouldn't we be deleting these?
	}
}

void LogicalChannel::connect()
{
	mMux.downstream(mL1);
	if (mL1) mL1->upstream(&mMux);
	for (int s=0; s<4; s++) {
		mMux.upstream(mL2[s],s);
		if (mL2[s]) mL2[s]->downstream(&mMux);
	}
}

void LogicalChannel::downstream(ARFCNManager* radio)
{
	assert(mL1);
	mL1->downstream(radio);
	if (mSACCH) mSACCH->downstream(radio);
}

// Serialize and send an L3Message with a given primitive.
void LogicalChannel::send(const L3Message& msg,
		const GSM::Primitive& prim,
		unsigned SAPI)
{
	LOG(INFO) << "L3 SAP" << SAPI << " sending " << msg;
	send(L3Frame(msg,prim), SAPI);
}

CCCHLogicalChannel::CCCHLogicalChannel(const TDMAMapping& wMapping)
	:mRunning(false)
{
	mL1 = new CCCHL1FEC(wMapping);
	mL2[0] = new CCCHL2;
	connect();
}

void CCCHLogicalChannel::open()
{
	LogicalChannel::open();
	if (!mRunning) {
		mRunning=true;
		mServiceThread.start((void*(*)(void*))CCCHLogicalChannelServiceLoopAdapter,this);
	}
}

void CCCHLogicalChannel::serviceLoop()
{
	// build the idle frame
	static const L3PagingRequestType1 filler;
	static const L3Frame idleFrame(filler,UNIT_DATA);
	// prime the first idle frame
	LogicalChannel::send(idleFrame);
	// run the loop
	while (true) {
		L3Frame* frame = mQ.read();
		if (frame) {
			LogicalChannel::send(*frame);
			OBJLOG(DEBUG) << "CCCHLogicalChannel::serviceLoop sending " << *frame;
			delete frame;
		}
		if (mQ.size()==0) {
			LogicalChannel::send(idleFrame);
			OBJLOG(DEBUG) << "CCCHLogicalChannel::serviceLoop sending idle frame";
		}
	}
}

void *GSM::CCCHLogicalChannelServiceLoopAdapter(CCCHLogicalChannel* chan)
{
	chan->serviceLoop();
	return NULL;
}

L3ChannelDescription LogicalChannel::channelDescription() const
{
	// In some debug cases, L1 may not exist, so we fake this information.
	if (mL1==NULL) return L3ChannelDescription(TDMA_MISC,0,0,0);

	// In normal cases, we get this information from L1.
	return L3ChannelDescription(
		mL1->typeAndOffset(),
		mL1->TN(),
		mL1->TSC(),
		mL1->ARFCN()
	);
}

SDCCHLogicalChannel::SDCCHLogicalChannel(
		unsigned wCN,
		unsigned wTN,
		const CompleteMapping& wMapping)
{
	mL1 = new SDCCHL1FEC(wCN,wTN,wMapping.LCH());
	// SAP0 is RR/MM/CC, SAP3 is SMS
	// SAP1 and SAP2 are not used.
	L2LAPDm *SAP0L2 = new SDCCHL2(1,0);
	L2LAPDm *SAP3L2 = new SDCCHL2(1,3);
	LOG(DEBUG) << "LAPDm pairs SAP0=" << SAP0L2 << " SAP3=" << SAP3L2;
	SAP3L2->master(SAP0L2);
	mL2[0] = SAP0L2;
	mL2[3] = SAP3L2;
	mSACCH = new SACCHLogicalChannel(wCN,wTN,wMapping.SACCH());
	connect();
}

SACCHLogicalChannel::SACCHLogicalChannel(
		unsigned wCN,
		unsigned wTN,
		const MappingPair& wMapping)
		: mRunning(false)
{
	mSACCHL1 = new SACCHL1FEC(wCN,wTN,wMapping);
	mL1 = mSACCHL1;
	// SAP0 is RR, SAP3 is SMS
	// SAP1 and SAP2 are not used.
	mL2[0] = new SACCHL2(1,0);
	mL2[3] = new SACCHL2(1,3);
	connect();
	assert(mSACCH==NULL);
}

void SACCHLogicalChannel::open()
{
	LogicalChannel::open();
	if (!mRunning) {
		mRunning=true;
		mServiceThread.start((void*(*)(void*))SACCHLogicalChannelServiceLoopAdapter,this);
	}
}

L3Message* processSACCHMessage(L3Frame *l3frame)
{
	if (!l3frame) return NULL;
	LOG(DEBUG) << *l3frame;
	Primitive prim = l3frame->primitive();
	if ((prim!=DATA) && (prim!=UNIT_DATA)) {
		LOG(INFO) << "non-data primitive " << prim;
		return NULL;
	}
	// FIXME -- Why, again, do we need to do this?
//	L3Frame realFrame = l3frame->segment(24, l3frame->size()-24);
	L3Message* message = parseL3(*l3frame);
	if (!message) {
		LOG(WARNING) << "SACCH recevied unparsable L3 frame " << *l3frame;
	}
	return message;
}

void SACCHLogicalChannel::serviceLoop()
{
	// run the loop
	unsigned count = 0;
	while (true) {

		// Throttle back if not active.
		if (!active()) {
			OBJLOG(DEBUG) << "SACCH sleeping";
			sleepFrames(51);
			continue;
		}

		// TODO SMS -- Check to see if the tx queues are empty.  If so, send SI5/6,
		// otherwise sleep and continue;

		// Send alternating SI5/SI6.
		OBJLOG(DEBUG) << "sending SI5/6 on SACCH";
		if (count%2) LogicalChannel::send(gBTS.SI5Frame());
		else LogicalChannel::send(gBTS.SI6Frame());
		count++;

		// Receive inbound messages.
		// This read loop flushes stray reports quickly.
		while (true) {

			OBJLOG(DEBUG) << "polling SACCH for inbound messages";
			bool nothing = true;

			// Process SAP0 -- RR Measurement reports
			L3Frame *rrFrame = LogicalChannel::recv(0,0);
			if (rrFrame) nothing=false;
			L3Message* rrMessage = processSACCHMessage(rrFrame);
			delete rrFrame;
			if (rrMessage) {
				L3MeasurementReport* measurement = dynamic_cast<L3MeasurementReport*>(rrMessage);
				if (measurement) {
					mMeasurementResults = measurement->results();
					OBJLOG(DEBUG) << "SACCH measurement report " << mMeasurementResults;
					// Add the measurement results to the table
					// Note that the typeAndOffset of a SACCH match the host channel.
					gPhysStatus.setPhysical(this, mMeasurementResults);
				} else {
					OBJLOG(NOTICE) << "SACCH SAP0 sent unaticipated message " << rrMessage;
				}
				delete rrMessage;
			}

			// Process SAP3 -- SMS
			L3Frame *smsFrame = LogicalChannel::recv(0,3);
			if (smsFrame) nothing=false;
			L3Message* smsMessage = processSACCHMessage(smsFrame);
			delete smsFrame;
			if (smsMessage) {
				const SMS::CPData* cpData = dynamic_cast<const SMS::CPData*>(smsMessage);
				if (cpData) {
					OBJLOG(INFO) << "SMS CPDU " << *cpData;
					Control::TransactionEntry *transaction = gTransactionTable.find(this);
					try {
						if (transaction) {
							Control::InCallMOSMSController(cpData,transaction,this);
						} else {
							OBJLOG(WARNING) << "in-call MOSMS CP-DATA with no corresponding transaction";
						}
					} catch (Control::ControlLayerException e) {
						//LogicalChannel::send(RELEASE,3);
						gTransactionTable.remove(e.transactionID());
					}
				} else {
					OBJLOG(NOTICE) << "SACCH SAP3 sent unaticipated message " << rrMessage;
				}
				delete smsMessage;
			}

			// Anything from the SIP side?
			// MTSMS (delivery from SIP to the MS)
			Control::TransactionEntry *sipTransaction = mTransactionFIFO.readNoBlock();
			if (sipTransaction) {
				OBJLOG(INFO) << "SIP-side transaction: " << sipTransaction;
				assert(sipTransaction->service() == L3CMServiceType::MobileTerminatedShortMessage);
				try {
					Control::MTSMSController(sipTransaction,this);
				} catch (Control::ControlLayerException e) {
					//LogicalChannel::send(RELEASE,3);
					gTransactionTable.remove(e.transactionID());
				}
			}

			// Nothing happened?
			if (nothing) break;
		}

	}
}

void *GSM::SACCHLogicalChannelServiceLoopAdapter(SACCHLogicalChannel* chan)
{
	chan->serviceLoop();
	return NULL;
}

// These have to go into the .cpp file to prevent an illegal forward reference.
void LogicalChannel::setPhy(float wRSSI, float wTimingError)
	{ assert(mSACCH); mSACCH->setPhy(wRSSI,wTimingError); }
void LogicalChannel::setPhy(const LogicalChannel& other)
	{ assert(mSACCH); mSACCH->setPhy(*other.SACCH()); }
float LogicalChannel::RSSI() const
	{ assert(mSACCH); return mSACCH->RSSI(); }
float LogicalChannel::timingError() const
	{ assert(mSACCH); return mSACCH->timingError(); }
int LogicalChannel::actualMSPower() const
	{ assert(mSACCH); return mSACCH->actualMSPower(); }
int LogicalChannel::actualMSTiming() const
	{ assert(mSACCH); return mSACCH->actualMSTiming(); }

TCHFACCHLogicalChannel::TCHFACCHLogicalChannel(
		unsigned wCN,
		unsigned wTN,
		const CompleteMapping& wMapping)
{
	mTCHL1 = new TCHFACCHL1FEC(wCN,wTN,wMapping.LCH());
	mL1 = mTCHL1;
	// SAP0 is RR/MM/CC, SAP3 is SMS
	// SAP1 and SAP2 are not used.
	mL2[0] = new FACCHL2(1,0);
	mL2[3] = new FACCHL2(1,3);
	mSACCH = new SACCHLogicalChannel(wCN,wTN,wMapping.SACCH());
	connect();
}

bool LogicalChannel::waitForPrimitive(Primitive primitive, unsigned timeout_ms)
{
	bool waiting = true;
	while (waiting) {
		L3Frame *req = recv(timeout_ms);
		if (req==NULL) {
			LOG(NOTICE) << "timeout at uptime " << gBTS.uptime() << " frame " << gBTS.time();
			return false;
		}
		waiting = (req->primitive()!=primitive);
		delete req;
	}
	return true;
}

void LogicalChannel::waitForPrimitive(Primitive primitive)
{
	bool waiting = true;
	while (waiting) {
		L3Frame *req = recv();
		if (req==NULL) continue;
		waiting = (req->primitive()!=primitive);
		delete req;
	}
}

ostream& GSM::operator<<(ostream& os, const LogicalChannel& chan)
{
	os << chan.descriptiveString();
	return os;
}

void LogicalChannel::addTransaction(Control::TransactionEntry *transaction)
{
	assert(transaction->channel()==this);
	mTransactionFIFO.write(transaction);
}

// vim: ts=4 sw=4

<|endoftext|>


<commit_before>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 * RLP tool.
 */
#include <fstream>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <libdevcore/CommonIO.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
using namespace std;
using namespace dev;

void help()
{
	cout
		<< "Usage rlp [OPTIONS] [ <file> | -- ]" << endl
		<< "Options:" << endl
		<< "    -r,--render  Render the given RLP. Options:" << endl
		<< "      --indent <string>  Use string as the level indentation (default '  ')." << endl
		<< "      --hex-ints  Render integers in hex." << endl
		<< "      --force-string  Force all data to be rendered as C-style strings." << endl
		<< "      --force-escape  When rendering as C-style strings, force all characters to be escaped." << endl
		<< "      --force-hex  Force all data to be rendered as raw hex." << endl
		<< "    -l,--list-archive  List the items in the RLP list by hash and size." << endl
		<< "    -e,--extract-archive  Extract all items in the RLP list, named by hash." << endl
		<< "General options:" << endl
		<< "    -L,--lenience  Try not to bomb out early if possible." << endl
		<< "    -x,--hex,--base-16  Treat input RLP as hex encoded data." << endl
		<< "    --64,--base-64  Treat input RLP as base-64 encoded data." << endl
		<< "    -b,--bin,--base-256  Treat input RLP as raw binary data." << endl
		<< "    -h,--help  Print this help message and exit." << endl
		<< "    -V,--version  Show the version and exit." << endl
		;
	exit(0);
}

void version()
{
	cout << "rlp version " << dev::Version << endl;
	exit(0);
}

enum class Mode {
	ListArchive,
	ExtractArchive,
	Render,
};

enum class Encoding {
	Auto,
	Hex,
	Base64,
	Binary,
};

bool isAscii(string const& _s)
{
	for (char c: _s)
		if (c < 32)
			return false;
	return true;
}

class RLPStreamer
{
public:
	struct Prefs
	{
		string indent = "  ";
		bool hexInts = false;
		bool forceString = false;
		bool escapeAll = false;
		bool forceHex = false;
	};

	RLPStreamer(ostream& _out, Prefs _p): m_out(_out), m_prefs(_p) {}

	void output(RLP const& _d, unsigned _level = 0)
	{
		if (_d.isNull())
			m_out << "null";
		else if (_d.isInt())
			if (m_prefs.hexInts)
				m_out << toHex(toCompactBigEndian(_d.toInt<bigint>(RLP::LaisezFaire), 1), 1);
			else
				m_out << _d.toInt<bigint>(RLP::LaisezFaire);
		else if (_d.isData())
			if (m_prefs.forceString || (!m_prefs.forceHex && isAscii(_d.toString())))
				m_out << escaped(_d.toString(), m_prefs.escapeAll);
			else
				m_out << toHex(_d.data());
		else if (_d.isList())
		{
			m_out << "[";
			string newline = "\n";
			for (unsigned i = 0; i < _level + 1; ++i)
				newline += m_prefs.indent;
			int j = 0;
			for (auto i: _d)
			{
				m_out << (j++ ?
					(m_prefs.indent.empty() ? ", " : ("," + newline)) :
					(m_prefs.indent.empty() ? " " : newline));
				output(i, _level + 1);
			}
			newline = newline.substr(0, newline.size() - m_prefs.indent.size());
			m_out << (m_prefs.indent.empty() ? (j ? " ]" : "]") : (j ? newline + "]" : "]"));
		}
	}

private:
	std::ostream& m_out;
	Prefs m_prefs;
};

int main(int argc, char** argv)
{
	Encoding encoding = Encoding::Auto;
	Mode mode = Mode::Render;
	string inputFile = "--";
	bool lenience = false;
	RLPStreamer::Prefs prefs;

	for (int i = 1; i < argc; ++i)
	{
		string arg = argv[i];
		if (arg == "-h" || arg == "--help")
			help();
		else if (arg == "-r" || arg == "--render")
			mode = Mode::Render;
		else if ((arg == "-i" || arg == "--indent") && argc > i)
			prefs.indent = argv[++i];
		else if (arg == "--hex-ints")
			prefs.hexInts = true;
		else if (arg == "--force-string")
			prefs.forceString = true;
		else if (arg == "--force-hex")
			prefs.forceHex = true;
		else if (arg == "--force-escape")
			prefs.escapeAll = true;
		else if (arg == "-l" || arg == "--list-archive")
			mode = Mode::ListArchive;
		else if (arg == "-e" || arg == "--extract-archive")
			mode = Mode::ExtractArchive;
		else if (arg == "-L" || arg == "--lenience")
			lenience = true;
		else if (arg == "-V" || arg == "--version")
			version();
		else if (arg == "-x" || arg == "--hex" || arg == "--base-16")
			encoding = Encoding::Hex;
		else if (arg == "--64" || arg == "--base-64")
			encoding = Encoding::Base64;
		else if (arg == "-b" || arg == "--bin" || arg == "--base-256")
			encoding = Encoding::Binary;
		else
			inputFile = arg;
	}

	bytes in;
	if (inputFile == "--")
		for (int i = cin.get(); i != -1; i = cin.get())
			in.push_back((byte)i);
	else
		in = contents(inputFile);
	if (encoding == Encoding::Auto)
	{
		encoding = Encoding::Hex;
		for (char b: in)
			if (b != '\n' && b != ' ' && b != '\t')
			{
				if (encoding == Encoding::Hex && (b < '0' || b > '9' ) && (b < 'a' || b > 'f' ) && (b < 'A' || b > 'F' ))
				{
					cerr << "'" << b << "':" << (int)b << endl;
					encoding = Encoding::Base64;
				}
				if (encoding == Encoding::Base64 && (b < '0' || b > '9' ) && (b < 'a' || b > 'z' ) && (b < 'A' || b > 'Z' ) && b != '+' && b != '/')
				{
					encoding = Encoding::Binary;
					break;
				}
			}
	}
	bytes b;
	switch (encoding)
	{
	case Encoding::Hex:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = fromHex(s);
		break;
	}
	case Encoding::Base64:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = fromBase64(s);
		break;
	}
	default:
		swap(b, in);
		break;
	}

	try
	{
		RLP rlp(b);
		switch (mode)
		{
		case Mode::ListArchive:
		{
			if (!rlp.isList())
			{
				cout << "Error: Invalid format; RLP data is not a list." << endl;
				exit(1);
			}
			cout << rlp.itemCount() << " items:" << endl;
			for (auto i: rlp)
			{
				if (!i.isData())
				{
					cout << "Error: Invalid format; RLP list item is not data." << endl;
					if (!lenience)
						exit(1);
				}
				cout << "    " << i.size() << " bytes: " << sha3(i.data()) << endl;
			}
			break;
		}
		case Mode::ExtractArchive:
		{
			if (!rlp.isList())
			{
				cout << "Error: Invalid format; RLP data is not a list." << endl;
				exit(1);
			}
			cout << rlp.itemCount() << " items:" << endl;
			for (auto i: rlp)
			{
				if (!i.isData())
				{
					cout << "Error: Invalid format; RLP list item is not data." << endl;
					if (!lenience)
						exit(1);
				}
				ofstream fout;
				fout.open(toString(sha3(i.data())));
				fout.write(reinterpret_cast<char const*>(i.data().data()), i.data().size());
			}
			break;
		}
		case Mode::Render:
		{
			RLPStreamer s(cout, prefs);
			s.output(rlp);
			cout << endl;
			break;
		}
		default:;
		}
	}
	catch (...)
	{
		cerr << "Error: Invalid format; bad RLP." << endl;
		exit(1);
	}

	return 0;
}
<commit_msg>Make RLP JSON compatible by default.<commit_after>/*
	This file is part of cpp-ethereum.

	cpp-ethereum is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	cpp-ethereum is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file main.cpp
 * @author Gav Wood <i@gavwood.com>
 * @date 2014
 * RLP tool.
 */
#include <fstream>
#include <iostream>
#include <boost/algorithm/string.hpp>
#include <libdevcore/CommonIO.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
using namespace std;
using namespace dev;

void help()
{
	cout
		<< "Usage rlp [OPTIONS] [ <file> | -- ]" << endl
		<< "Options:" << endl
		<< "    -r,--render  Render the given RLP. Options:" << endl
		<< "      --indent <string>  Use string as the level indentation (default '  ')." << endl
		<< "      --hex-ints  Render integers in hex." << endl
		<< "      --ascii-strings  Render data as C-style strings or hex depending on content being ASCII." << endl
		<< "      --force-string  Force all data to be rendered as C-style strings." << endl
		<< "      --force-escape  When rendering as C-style strings, force all characters to be escaped." << endl
		<< "      --force-hex  Force all data to be rendered as raw hex." << endl
		<< "    -l,--list-archive  List the items in the RLP list by hash and size." << endl
		<< "    -e,--extract-archive  Extract all items in the RLP list, named by hash." << endl
		<< "General options:" << endl
		<< "    -L,--lenience  Try not to bomb out early if possible." << endl
		<< "    -x,--hex,--base-16  Treat input RLP as hex encoded data." << endl
		<< "    --64,--base-64  Treat input RLP as base-64 encoded data." << endl
		<< "    -b,--bin,--base-256  Treat input RLP as raw binary data." << endl
		<< "    -h,--help  Print this help message and exit." << endl
		<< "    -V,--version  Show the version and exit." << endl
		;
	exit(0);
}

void version()
{
	cout << "rlp version " << dev::Version << endl;
	exit(0);
}

enum class Mode {
	ListArchive,
	ExtractArchive,
	Render,
};

enum class Encoding {
	Auto,
	Hex,
	Base64,
	Binary,
};

bool isAscii(string const& _s)
{
	for (char c: _s)
		if (c < 32)
			return false;
	return true;
}

class RLPStreamer
{
public:
	struct Prefs
	{
		string indent = "  ";
		bool hexInts = false;
		bool forceString = true;
		bool escapeAll = false;
		bool forceHex = false;
	};

	RLPStreamer(ostream& _out, Prefs _p): m_out(_out), m_prefs(_p) {}

	void output(RLP const& _d, unsigned _level = 0)
	{
		if (_d.isNull())
			m_out << "null";
		else if (_d.isInt())
			if (m_prefs.hexInts)
				m_out << toHex(toCompactBigEndian(_d.toInt<bigint>(RLP::LaisezFaire), 1), 1);
			else
				m_out << _d.toInt<bigint>(RLP::LaisezFaire);
		else if (_d.isData())
			if (m_prefs.forceString || (!m_prefs.forceHex && isAscii(_d.toString())))
				m_out << escaped(_d.toString(), m_prefs.escapeAll);
			else
				m_out << toHex(_d.data());
		else if (_d.isList())
		{
			m_out << "[";
			string newline = "\n";
			for (unsigned i = 0; i < _level + 1; ++i)
				newline += m_prefs.indent;
			int j = 0;
			for (auto i: _d)
			{
				m_out << (j++ ?
					(m_prefs.indent.empty() ? ", " : ("," + newline)) :
					(m_prefs.indent.empty() ? " " : newline));
				output(i, _level + 1);
			}
			newline = newline.substr(0, newline.size() - m_prefs.indent.size());
			m_out << (m_prefs.indent.empty() ? (j ? " ]" : "]") : (j ? newline + "]" : "]"));
		}
	}

private:
	std::ostream& m_out;
	Prefs m_prefs;
};

int main(int argc, char** argv)
{
	Encoding encoding = Encoding::Auto;
	Mode mode = Mode::Render;
	string inputFile = "--";
	bool lenience = false;
	RLPStreamer::Prefs prefs;

	for (int i = 1; i < argc; ++i)
	{
		string arg = argv[i];
		if (arg == "-h" || arg == "--help")
			help();
		else if (arg == "-r" || arg == "--render")
			mode = Mode::Render;
		else if ((arg == "-i" || arg == "--indent") && argc > i)
			prefs.indent = argv[++i];
		else if (arg == "--hex-ints")
			prefs.hexInts = true;
		else if (arg == "--ascii-strings")
			prefs.forceString = prefs.forceHex = false;
		else if (arg == "--force-string")
			prefs.forceString = true;
		else if (arg == "--force-hex")
			prefs.forceHex = true;
		else if (arg == "--force-escape")
			prefs.escapeAll = true;
		else if (arg == "-l" || arg == "--list-archive")
			mode = Mode::ListArchive;
		else if (arg == "-e" || arg == "--extract-archive")
			mode = Mode::ExtractArchive;
		else if (arg == "-L" || arg == "--lenience")
			lenience = true;
		else if (arg == "-V" || arg == "--version")
			version();
		else if (arg == "-x" || arg == "--hex" || arg == "--base-16")
			encoding = Encoding::Hex;
		else if (arg == "--64" || arg == "--base-64")
			encoding = Encoding::Base64;
		else if (arg == "-b" || arg == "--bin" || arg == "--base-256")
			encoding = Encoding::Binary;
		else
			inputFile = arg;
	}

	bytes in;
	if (inputFile == "--")
		for (int i = cin.get(); i != -1; i = cin.get())
			in.push_back((byte)i);
	else
		in = contents(inputFile);
	if (encoding == Encoding::Auto)
	{
		encoding = Encoding::Hex;
		for (char b: in)
			if (b != '\n' && b != ' ' && b != '\t')
			{
				if (encoding == Encoding::Hex && (b < '0' || b > '9' ) && (b < 'a' || b > 'f' ) && (b < 'A' || b > 'F' ))
				{
					cerr << "'" << b << "':" << (int)b << endl;
					encoding = Encoding::Base64;
				}
				if (encoding == Encoding::Base64 && (b < '0' || b > '9' ) && (b < 'a' || b > 'z' ) && (b < 'A' || b > 'Z' ) && b != '+' && b != '/')
				{
					encoding = Encoding::Binary;
					break;
				}
			}
	}
	bytes b;
	switch (encoding)
	{
	case Encoding::Hex:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = fromHex(s);
		break;
	}
	case Encoding::Base64:
	{
		string s = asString(in);
		boost::algorithm::replace_all(s, " ", "");
		boost::algorithm::replace_all(s, "\n", "");
		boost::algorithm::replace_all(s, "\t", "");
		b = fromBase64(s);
		break;
	}
	default:
		swap(b, in);
		break;
	}

	try
	{
		RLP rlp(b);
		switch (mode)
		{
		case Mode::ListArchive:
		{
			if (!rlp.isList())
			{
				cout << "Error: Invalid format; RLP data is not a list." << endl;
				exit(1);
			}
			cout << rlp.itemCount() << " items:" << endl;
			for (auto i: rlp)
			{
				if (!i.isData())
				{
					cout << "Error: Invalid format; RLP list item is not data." << endl;
					if (!lenience)
						exit(1);
				}
				cout << "    " << i.size() << " bytes: " << sha3(i.data()) << endl;
			}
			break;
		}
		case Mode::ExtractArchive:
		{
			if (!rlp.isList())
			{
				cout << "Error: Invalid format; RLP data is not a list." << endl;
				exit(1);
			}
			cout << rlp.itemCount() << " items:" << endl;
			for (auto i: rlp)
			{
				if (!i.isData())
				{
					cout << "Error: Invalid format; RLP list item is not data." << endl;
					if (!lenience)
						exit(1);
				}
				ofstream fout;
				fout.open(toString(sha3(i.data())));
				fout.write(reinterpret_cast<char const*>(i.data().data()), i.data().size());
			}
			break;
		}
		case Mode::Render:
		{
			RLPStreamer s(cout, prefs);
			s.output(rlp);
			cout << endl;
			break;
		}
		default:;
		}
	}
	catch (...)
	{
		cerr << "Error: Invalid format; bad RLP." << endl;
		exit(1);
	}

	return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: fieldwnd.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: hr $ $Date: 2003-03-26 18:06:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FIELDWND_HXX
#define SC_FIELDWND_HXX

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#define MAX_LABELS  256
#define PAGE_SIZE   16      // count of visible fields for scrollbar
#define LINE_SIZE   8       // count of fields per column for scrollbar
#define MAX_FIELDS  8       // maximum count of fields for row/col/data area

#define OWIDTH  PivotGlobal::nObjWidth
#define OHEIGHT PivotGlobal::nObjHeight
#define SSPACE  PivotGlobal::nSelSpace

class ScDPLayoutDlg;
class ScAccessibleDataPilotControl;

//===================================================================

/** Type of content area. */
enum ScDPFieldType
{
    TYPE_ROW,               /// Area for all row fields.
    TYPE_COL,               /// Area for all column fields.
    TYPE_DATA,              /// Area for all data fields.
    TYPE_SELECT             /// Selection area with all fields.
};

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

/** Represents a field area in the DataPilot layout dialog. */
class ScDPFieldWindow : public Control
{
private:
    String                  aName;          /// name of the control, used in Accessibility
    ScDPLayoutDlg*          pDlg;           /// Parent dialog.
    Rectangle               aWndRect;       /// Area rectangle in pixels.
    FixedText*              pFtCaption;     /// FixedText containing the name of the control.
    Point                   aTextPos;       /// Position of the caption text.
    String**                aFieldArr;      /// Pointer to string array of the field names.
    ScDPFieldType           eType;          /// Type of this area.
    Color                   aFaceColor;     /// Color for dialog background.
    Color                   aWinColor;      /// Color for window background.
    Color                   aTextColor;     /// Color for text in buttons.
    Color                   aWinTextColor;  /// Color for text in field windows.
    long                    nFieldSize;     /// Maximum count of fields.
    long                    nFieldCount;    /// Count of existing fields.
    long                    nFieldSelected; /// Currently selected field.
    bool                    mbAppRTL;       /// true = Application in RTL display mode.

    com::sun::star::uno::WeakReference< ::drafts::com::sun::star::accessibility::XAccessible > xAccessible;
    ScAccessibleDataPilotControl* pAccessible;

    /** Initilize the object. */
    void                    Init();

    /** Reads all needed style settings. */
    void                    GetStyleSettings();

    /** Draws the background. */
    void                    DrawBackground( OutputDevice& rDev );
    /** Draws a field into the specified rectangle. */
    void                    DrawField(
                                OutputDevice& rDev,
                                const Rectangle& rRect,
                                const String& rText,
                                BOOL bSelected );

    /** @return  TRUE, if the field index is inside of the control area. */
    BOOL                    IsValidIndex( long nIndex ) const;
    /** @return  TRUE, if the field with the given index exists. */
    BOOL                    IsExistingIndex( long nIndex ) const;
    /** @return  The new selection index after moving to the given direction. */
    long                    CalcNewFieldIndex( short nDX, short nDY ) const;

    /** Sets selection to the field with index nIndex. */
    void                    SetSelection( long nIndex );
    /** Sets selection to first field. */
    void                    SetSelectionHome();
    /** Sets selection to last field. */
    void                    SetSelectionEnd();
    /** Sets selection to new position relative to current. */
    void                    MoveSelection( USHORT nKeyCode, short nDX, short nDY );

    /** Moves the selected field to nDestIndex. */
    void                    MoveField( long nDestIndex );
    /** Moves the selected field to the given direction. */
    void                    MoveFieldRel( short nDX, short nDY );

protected:
    virtual void            Paint( const Rectangle& rRect );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );
    virtual void            MouseButtonDown( const MouseEvent& rMEvt );
    virtual void            MouseButtonUp( const MouseEvent& rMEvt );
    virtual void            MouseMove( const MouseEvent& rMEvt );
    virtual void            KeyInput( const KeyEvent& rKEvt );
    virtual void            GetFocus();
    virtual void            LoseFocus();
    virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > CreateAccessible();

public:
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                FixedText* pFtFieldCaption );
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                const String& aName );
    virtual                 ~ScDPFieldWindow();

    /** Draws the complete control. */
    void                    Redraw();

    /** @return  The pixel position of a field (without bound check). */
    Point                   GetFieldPosition( long nIndex ) const;
    /** @return  The pixel size of a field. */
    Size                    GetFieldSize() const;

    /** @return  The index of the selected field. */
    inline BOOL             IsEmpty() const             { return nFieldCount == 0; }
    /** @return  The index of the selected field. */
    inline long             GetSelectedField() const    { return nFieldSelected; }
    /** @return  The pixel position of the last possible field. */
    Point                   GetLastPosition() const;

    /** @return  The count of existing fields. */
    long                    GetFieldCount() const       { return nFieldCount; }
    /** Inserts a field to the specified index. */
    void                    AddField( const String& rText, long nNewIndex );
    /** Removes a field from the specified index. */
    void                    DelField( long nDelIndex );
    /** Removes all fields. */
    void                    ClearFields();
    /** Changes the text on an existing field. */
    void                    SetFieldText( const String& rText, long nIndex );
    /** Returns the text of an existing field. */
    const String&           GetFieldText(long nIndex) const;

    /** Inserts a field using the specified pixel position.
        @param rPos  The coordinates to insert the field.
        @param rnIndex  The new index of the field is returned here.
        @return  TRUE, if the field has been created. */
    BOOL                    AddField( const String& rText, const Point& rPos, long& rnIndex );
    /** Calculates the field index at a specific pixel position.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    BOOL                    GetFieldIndex( const Point& rPos, long& rnIndex ) const;
    /** Calculates a field index at a specific pixel position. Returns in every
        case the index of an existing field.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    void                    GetExistingIndex( const Point& rPos, long& rnIndex );

    /** Notifies this control that the offset of the first field has been changed.
        The control has to adjust the selection to keep the same field selected
        on scrolling with scrollbar. */
    void                    ModifySelectionOffset( long nOffsetDiff );
    /** Selects the next field. Called i.e. after moving a field from SELECT area. */
    void                    SelectNext();

    /** @return The name of the control without shortcut. */
    String                  GetName()const              { return aName; }

    /** @return The description of the control which is used for the accessibility objects. */
    String                  GetDescription()const;

    /** Grabs focus and sets new selection. */
    void                    GrabFocusWithSel( long nIndex );

    /** @return The type of the FieldWindow. */
    ScDPFieldType           GetType() const { return eType; }
};

//===================================================================

#endif // SC_FIELDWND_HXX
<commit_msg>INTEGRATION: CWS vcl08 (1.6.2.1.20); FILE MERGED 2003/04/09 10:19:45 dr 1.6.2.1.20.1: #108669# mirrored UI: swap left/right cursor done in VCL<commit_after>/*************************************************************************
 *
 *  $RCSfile: fieldwnd.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2003-04-17 15:09:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SC_FIELDWND_HXX
#define SC_FIELDWND_HXX

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#define MAX_LABELS  256
#define PAGE_SIZE   16      // count of visible fields for scrollbar
#define LINE_SIZE   8       // count of fields per column for scrollbar
#define MAX_FIELDS  8       // maximum count of fields for row/col/data area

#define OWIDTH  PivotGlobal::nObjWidth
#define OHEIGHT PivotGlobal::nObjHeight
#define SSPACE  PivotGlobal::nSelSpace

class ScDPLayoutDlg;
class ScAccessibleDataPilotControl;

//===================================================================

/** Type of content area. */
enum ScDPFieldType
{
    TYPE_ROW,               /// Area for all row fields.
    TYPE_COL,               /// Area for all column fields.
    TYPE_DATA,              /// Area for all data fields.
    TYPE_SELECT             /// Selection area with all fields.
};

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

/** Represents a field area in the DataPilot layout dialog. */
class ScDPFieldWindow : public Control
{
private:
    String                  aName;          /// name of the control, used in Accessibility
    ScDPLayoutDlg*          pDlg;           /// Parent dialog.
    Rectangle               aWndRect;       /// Area rectangle in pixels.
    FixedText*              pFtCaption;     /// FixedText containing the name of the control.
    Point                   aTextPos;       /// Position of the caption text.
    String**                aFieldArr;      /// Pointer to string array of the field names.
    ScDPFieldType           eType;          /// Type of this area.
    Color                   aFaceColor;     /// Color for dialog background.
    Color                   aWinColor;      /// Color for window background.
    Color                   aTextColor;     /// Color for text in buttons.
    Color                   aWinTextColor;  /// Color for text in field windows.
    long                    nFieldSize;     /// Maximum count of fields.
    long                    nFieldCount;    /// Count of existing fields.
    long                    nFieldSelected; /// Currently selected field.

    com::sun::star::uno::WeakReference< ::drafts::com::sun::star::accessibility::XAccessible > xAccessible;
    ScAccessibleDataPilotControl* pAccessible;

    /** Initilize the object. */
    void                    Init();

    /** Reads all needed style settings. */
    void                    GetStyleSettings();

    /** Draws the background. */
    void                    DrawBackground( OutputDevice& rDev );
    /** Draws a field into the specified rectangle. */
    void                    DrawField(
                                OutputDevice& rDev,
                                const Rectangle& rRect,
                                const String& rText,
                                BOOL bSelected );

    /** @return  TRUE, if the field index is inside of the control area. */
    BOOL                    IsValidIndex( long nIndex ) const;
    /** @return  TRUE, if the field with the given index exists. */
    BOOL                    IsExistingIndex( long nIndex ) const;
    /** @return  The new selection index after moving to the given direction. */
    long                    CalcNewFieldIndex( short nDX, short nDY ) const;

    /** Sets selection to the field with index nIndex. */
    void                    SetSelection( long nIndex );
    /** Sets selection to first field. */
    void                    SetSelectionHome();
    /** Sets selection to last field. */
    void                    SetSelectionEnd();
    /** Sets selection to new position relative to current. */
    void                    MoveSelection( USHORT nKeyCode, short nDX, short nDY );

    /** Moves the selected field to nDestIndex. */
    void                    MoveField( long nDestIndex );
    /** Moves the selected field to the given direction. */
    void                    MoveFieldRel( short nDX, short nDY );

protected:
    virtual void            Paint( const Rectangle& rRect );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );
    virtual void            MouseButtonDown( const MouseEvent& rMEvt );
    virtual void            MouseButtonUp( const MouseEvent& rMEvt );
    virtual void            MouseMove( const MouseEvent& rMEvt );
    virtual void            KeyInput( const KeyEvent& rKEvt );
    virtual void            GetFocus();
    virtual void            LoseFocus();
    virtual ::com::sun::star::uno::Reference< ::drafts::com::sun::star::accessibility::XAccessible > CreateAccessible();

public:
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                FixedText* pFtFieldCaption );
                            ScDPFieldWindow(
                                ScDPLayoutDlg* pDialog,
                                const ResId& rResId,
                                ScDPFieldType eFieldType,
                                const String& aName );
    virtual                 ~ScDPFieldWindow();

    /** Draws the complete control. */
    void                    Redraw();

    /** @return  The pixel position of a field (without bound check). */
    Point                   GetFieldPosition( long nIndex ) const;
    /** @return  The pixel size of a field. */
    Size                    GetFieldSize() const;

    /** @return  The index of the selected field. */
    inline BOOL             IsEmpty() const             { return nFieldCount == 0; }
    /** @return  The index of the selected field. */
    inline long             GetSelectedField() const    { return nFieldSelected; }
    /** @return  The pixel position of the last possible field. */
    Point                   GetLastPosition() const;

    /** @return  The count of existing fields. */
    long                    GetFieldCount() const       { return nFieldCount; }
    /** Inserts a field to the specified index. */
    void                    AddField( const String& rText, long nNewIndex );
    /** Removes a field from the specified index. */
    void                    DelField( long nDelIndex );
    /** Removes all fields. */
    void                    ClearFields();
    /** Changes the text on an existing field. */
    void                    SetFieldText( const String& rText, long nIndex );
    /** Returns the text of an existing field. */
    const String&           GetFieldText(long nIndex) const;

    /** Inserts a field using the specified pixel position.
        @param rPos  The coordinates to insert the field.
        @param rnIndex  The new index of the field is returned here.
        @return  TRUE, if the field has been created. */
    BOOL                    AddField( const String& rText, const Point& rPos, long& rnIndex );
    /** Calculates the field index at a specific pixel position.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    BOOL                    GetFieldIndex( const Point& rPos, long& rnIndex ) const;
    /** Calculates a field index at a specific pixel position. Returns in every
        case the index of an existing field.
        @param rnIndex  The index of the field is returned here.
        @return  TRUE, if the index value is valid. */
    void                    GetExistingIndex( const Point& rPos, long& rnIndex );

    /** Notifies this control that the offset of the first field has been changed.
        The control has to adjust the selection to keep the same field selected
        on scrolling with scrollbar. */
    void                    ModifySelectionOffset( long nOffsetDiff );
    /** Selects the next field. Called i.e. after moving a field from SELECT area. */
    void                    SelectNext();

    /** @return The name of the control without shortcut. */
    String                  GetName()const              { return aName; }

    /** @return The description of the control which is used for the accessibility objects. */
    String                  GetDescription()const;

    /** Grabs focus and sets new selection. */
    void                    GrabFocusWithSel( long nIndex );

    /** @return The type of the FieldWindow. */
    ScDPFieldType           GetType() const { return eType; }
};

//===================================================================

#endif // SC_FIELDWND_HXX
<|endoftext|>