<commit_before>/*
* (C) 2010,2014,2015 Jack Lloyd
* (C) 2015 René Korthaus
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "cli.h"

#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)

#include <botan/base64.h>

#include <botan/pk_keys.h>
#include <botan/pk_algs.h>
#include <botan/pkcs8.h>
#include <botan/pubkey.h>

#if defined(BOTAN_HAS_DL_GROUP)
   #include <botan/dl_group.h>
#endif

#if defined(BOTAN_HAS_ECC_GROUP)
   #include <botan/ec_group.h>
#endif

namespace Botan_CLI {

class PK_Keygen final : public Command
   {
   public:
      PK_Keygen() : Command("keygen --algo=RSA --params= --passphrase= --pbe= --pbe-millis=300 --der-out") {}

      void go() override
         {
         const std::string algo = get_arg("algo");
         const std::string params = get_arg("params");

         std::unique_ptr<Botan::Private_Key>
         key(Botan::create_private_key(algo, rng(), params));

         if(!key)
            {
            throw CLI_Error_Unsupported("keygen", algo);
            }

         const std::string pass = get_arg("passphrase");
         const bool der_out = flag_set("der-out");

         const std::chrono::milliseconds pbe_millis(get_arg_sz("pbe-millis"));
         const std::string pbe = get_arg("pbe");

         if(der_out)
            {
            if(pass.empty())
               {
               write_output(Botan::PKCS8::BER_encode(*key));
               }
            else
               {
               write_output(Botan::PKCS8::BER_encode(*key, rng(), pass, pbe_millis, pbe));
               }
            }
         else
            {
            if(pass.empty())
               {
               output() << Botan::PKCS8::PEM_encode(*key);
               }
            else
               {
               output() << Botan::PKCS8::PEM_encode(*key, rng(), pass, pbe_millis, pbe);
               }
            }
         }
   };

BOTAN_REGISTER_COMMAND("keygen", PK_Keygen);

namespace {

std::string algo_default_emsa(const std::string& key)
   {
   if(key == "RSA")
      {
      return "EMSA4";
      } // PSS
   else if(key == "ECDSA" || key == "DSA")
      {
      return "EMSA1";
      }
   else
      {
      return "EMSA1";
      }
   }

}

class PK_Sign final : public Command
   {
   public:
      PK_Sign() : Command("sign --passphrase= --hash=SHA-256 --emsa= key file") {}

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(
            Botan::PKCS8::load_key(
               get_arg("key"),
               rng(),
               get_arg("passphrase")));

         if(!key)
            {
            throw CLI_Error("Unable to load private key");
            }

         const std::string sig_padding =
            get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")";

         Botan::PK_Signer signer(*key, rng(), sig_padding);

         auto onData = [&signer](const uint8_t b[], size_t l)
            {
            signer.update(b, l);
            };
         this->read_file(get_arg("file"), onData);

         output() << Botan::base64_encode(signer.signature(rng())) << "\n";
         }
   };

BOTAN_REGISTER_COMMAND("sign", PK_Sign);

class PK_Verify final : public Command
   {
   public:
      PK_Verify() : Command("verify --hash=SHA-256 --emsa= pubkey file signature") {}

      void go() override
         {
         std::unique_ptr<Botan::Public_Key> key(Botan::X509::load_key(get_arg("pubkey")));
         if(!key)
            {
            throw CLI_Error("Unable to load public key");
            }

         const std::string sig_padding =
            get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")";

         Botan::PK_Verifier verifier(*key, sig_padding);
         auto onData = [&verifier](const uint8_t b[], size_t l)
            {
            verifier.update(b, l);
            };
         this->read_file(get_arg("file"), onData);

         const Botan::secure_vector<uint8_t> signature =
            Botan::base64_decode(this->slurp_file_as_str(get_arg("signature")));

         const bool valid = verifier.check_signature(signature);

         output() << "Signature is " << (valid ? "valid" : "invalid") << "\n";
         }
   };

BOTAN_REGISTER_COMMAND("verify", PK_Verify);

#if defined(BOTAN_HAS_ECC_GROUP)

class EC_Group_Info final : public Command
   {
   public:
      EC_Group_Info() : Command("ec_group_info --pem name") {}

      void go() override
         {
         Botan::EC_Group group(get_arg("name"));

         if(flag_set("pem"))
            {
            output() << group.PEM_encode();
            }
         else
            {
            output() << "P = " << std::hex << group.get_curve().get_p() << "\n"
                     << "A = " << std::hex << group.get_curve().get_a() << "\n"
                     << "B = " << std::hex << group.get_curve().get_b() << "\n"
                     << "G = " << group.get_base_point().get_affine_x() << ","
                     << group.get_base_point().get_affine_y() << "\n";
            }

         }
   };

BOTAN_REGISTER_COMMAND("ec_group_info", EC_Group_Info);

#endif

#if defined(BOTAN_HAS_DL_GROUP)

class DL_Group_Info final : public Command
   {
   public:
      DL_Group_Info() : Command("dl_group_info --pem name") {}

      void go() override
         {
         Botan::DL_Group group(get_arg("name"));

         if(flag_set("pem"))
            {
            output() << group.PEM_encode(Botan::DL_Group::ANSI_X9_42_DH_PARAMETERS);
            }
         else
            {
            output() << "P = " << std::hex << group.get_p() << "\n"
                     << "G = " << group.get_g() << "\n";
            }

         }
   };

BOTAN_REGISTER_COMMAND("dl_group_info", DL_Group_Info);

class Gen_DL_Group final : public Command
   {
   public:
      Gen_DL_Group() : Command("gen_dl_group --pbits=1024 --qbits=0 --type=subgroup") {}

      void go() override
         {
         const size_t pbits = get_arg_sz("pbits");

         const std::string type = get_arg("type");

         if(type == "strong")
            {
            Botan::DL_Group grp(rng(), Botan::DL_Group::Strong, pbits);
            output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42);
            }
         else if(type == "subgroup")
            {
            Botan::DL_Group grp(rng(), Botan::DL_Group::Prime_Subgroup, pbits, get_arg_sz("qbits"));
            output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42);
            }
         else
            {
            throw CLI_Usage_Error("Invalid DL type '" + type + "'");
            }
         }
   };

BOTAN_REGISTER_COMMAND("gen_dl_group", Gen_DL_Group);

#endif

class PKCS8_Tool final : public Command
   {
   public:
      PKCS8_Tool() : Command("pkcs8 --pass-in= --pub-out --der-out --pass-out= --pbe= --pbe-millis=300 key") {}

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(
            Botan::PKCS8::load_key(
               get_arg("key"),
               rng(),
               get_arg("pass-in")));

         const std::chrono::milliseconds pbe_millis(get_arg_sz("pbe-millis"));
         const std::string pbe = get_arg("pbe");
         const bool der_out = flag_set("der-out");

         if(flag_set("pub-out"))
            {
            if(der_out)
               {
               write_output(Botan::X509::BER_encode(*key));
               }
            else
               {
               output() << Botan::X509::PEM_encode(*key);
               }
            }
         else
            {
            const std::string pass = get_arg("pass-out");

            if(der_out)
               {
               if(pass.empty())
                  {
                  write_output(Botan::PKCS8::BER_encode(*key));
                  }
               else
                  {
                  write_output(Botan::PKCS8::BER_encode(*key, rng(), pass, pbe_millis, pbe));
                  }
               }
            else
               {
               if(pass.empty())
                  {
                  output() << Botan::PKCS8::PEM_encode(*key);
                  }
               else
                  {
                  output() << Botan::PKCS8::PEM_encode(*key, rng(), pass, pbe_millis, pbe);
                  }
               }
            }
         }
   };

BOTAN_REGISTER_COMMAND("pkcs8", PKCS8_Tool);

}

#endif
<commit_msg>Fix loading of unencrypted PKCS#8 key via CLI<commit_after>/*
* (C) 2010,2014,2015 Jack Lloyd
* (C) 2015 René Korthaus
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "cli.h"

#if defined(BOTAN_HAS_PUBLIC_KEY_CRYPTO)

#include <botan/base64.h>

#include <botan/pk_keys.h>
#include <botan/pk_algs.h>
#include <botan/pkcs8.h>
#include <botan/pubkey.h>

#if defined(BOTAN_HAS_DL_GROUP)
   #include <botan/dl_group.h>
#endif

#if defined(BOTAN_HAS_ECC_GROUP)
   #include <botan/ec_group.h>
#endif

namespace Botan_CLI {

class PK_Keygen final : public Command
   {
   public:
      PK_Keygen() : Command("keygen --algo=RSA --params= --passphrase= --pbe= --pbe-millis=300 --der-out") {}

      void go() override
         {
         const std::string algo = get_arg("algo");
         const std::string params = get_arg("params");

         std::unique_ptr<Botan::Private_Key>
         key(Botan::create_private_key(algo, rng(), params));

         if(!key)
            {
            throw CLI_Error_Unsupported("keygen", algo);
            }

         const std::string pass = get_arg("passphrase");
         const bool der_out = flag_set("der-out");

         const std::chrono::milliseconds pbe_millis(get_arg_sz("pbe-millis"));
         const std::string pbe = get_arg("pbe");

         if(der_out)
            {
            if(pass.empty())
               {
               write_output(Botan::PKCS8::BER_encode(*key));
               }
            else
               {
               write_output(Botan::PKCS8::BER_encode(*key, rng(), pass, pbe_millis, pbe));
               }
            }
         else
            {
            if(pass.empty())
               {
               output() << Botan::PKCS8::PEM_encode(*key);
               }
            else
               {
               output() << Botan::PKCS8::PEM_encode(*key, rng(), pass, pbe_millis, pbe);
               }
            }
         }
   };

BOTAN_REGISTER_COMMAND("keygen", PK_Keygen);

namespace {

std::string algo_default_emsa(const std::string& key)
   {
   if(key == "RSA")
      {
      return "EMSA4";
      } // PSS
   else if(key == "ECDSA" || key == "DSA")
      {
      return "EMSA1";
      }
   else
      {
      return "EMSA1";
      }
   }

}

class PK_Sign final : public Command
   {
   public:
      PK_Sign() : Command("sign --passphrase= --hash=SHA-256 --emsa= key file") {}

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key(
            Botan::PKCS8::load_key(
               get_arg("key"),
               rng(),
               get_arg("passphrase")));

         if(!key)
            {
            throw CLI_Error("Unable to load private key");
            }

         const std::string sig_padding =
            get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")";

         Botan::PK_Signer signer(*key, rng(), sig_padding);

         auto onData = [&signer](const uint8_t b[], size_t l)
            {
            signer.update(b, l);
            };
         this->read_file(get_arg("file"), onData);

         output() << Botan::base64_encode(signer.signature(rng())) << "\n";
         }
   };

BOTAN_REGISTER_COMMAND("sign", PK_Sign);

class PK_Verify final : public Command
   {
   public:
      PK_Verify() : Command("verify --hash=SHA-256 --emsa= pubkey file signature") {}

      void go() override
         {
         std::unique_ptr<Botan::Public_Key> key(Botan::X509::load_key(get_arg("pubkey")));
         if(!key)
            {
            throw CLI_Error("Unable to load public key");
            }

         const std::string sig_padding =
            get_arg_or("emsa", algo_default_emsa(key->algo_name())) + "(" + get_arg("hash") + ")";

         Botan::PK_Verifier verifier(*key, sig_padding);
         auto onData = [&verifier](const uint8_t b[], size_t l)
            {
            verifier.update(b, l);
            };
         this->read_file(get_arg("file"), onData);

         const Botan::secure_vector<uint8_t> signature =
            Botan::base64_decode(this->slurp_file_as_str(get_arg("signature")));

         const bool valid = verifier.check_signature(signature);

         output() << "Signature is " << (valid ? "valid" : "invalid") << "\n";
         }
   };

BOTAN_REGISTER_COMMAND("verify", PK_Verify);

#if defined(BOTAN_HAS_ECC_GROUP)

class EC_Group_Info final : public Command
   {
   public:
      EC_Group_Info() : Command("ec_group_info --pem name") {}

      void go() override
         {
         Botan::EC_Group group(get_arg("name"));

         if(flag_set("pem"))
            {
            output() << group.PEM_encode();
            }
         else
            {
            output() << "P = " << std::hex << group.get_curve().get_p() << "\n"
                     << "A = " << std::hex << group.get_curve().get_a() << "\n"
                     << "B = " << std::hex << group.get_curve().get_b() << "\n"
                     << "G = " << group.get_base_point().get_affine_x() << ","
                     << group.get_base_point().get_affine_y() << "\n";
            }

         }
   };

BOTAN_REGISTER_COMMAND("ec_group_info", EC_Group_Info);

#endif

#if defined(BOTAN_HAS_DL_GROUP)

class DL_Group_Info final : public Command
   {
   public:
      DL_Group_Info() : Command("dl_group_info --pem name") {}

      void go() override
         {
         Botan::DL_Group group(get_arg("name"));

         if(flag_set("pem"))
            {
            output() << group.PEM_encode(Botan::DL_Group::ANSI_X9_42_DH_PARAMETERS);
            }
         else
            {
            output() << "P = " << std::hex << group.get_p() << "\n"
                     << "G = " << group.get_g() << "\n";
            }

         }
   };

BOTAN_REGISTER_COMMAND("dl_group_info", DL_Group_Info);

class Gen_DL_Group final : public Command
   {
   public:
      Gen_DL_Group() : Command("gen_dl_group --pbits=1024 --qbits=0 --type=subgroup") {}

      void go() override
         {
         const size_t pbits = get_arg_sz("pbits");

         const std::string type = get_arg("type");

         if(type == "strong")
            {
            Botan::DL_Group grp(rng(), Botan::DL_Group::Strong, pbits);
            output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42);
            }
         else if(type == "subgroup")
            {
            Botan::DL_Group grp(rng(), Botan::DL_Group::Prime_Subgroup, pbits, get_arg_sz("qbits"));
            output() << grp.PEM_encode(Botan::DL_Group::ANSI_X9_42);
            }
         else
            {
            throw CLI_Usage_Error("Invalid DL type '" + type + "'");
            }
         }
   };

BOTAN_REGISTER_COMMAND("gen_dl_group", Gen_DL_Group);

#endif

class PKCS8_Tool final : public Command
   {
   public:
      PKCS8_Tool() : Command("pkcs8 --pass-in= --pub-out --der-out --pass-out= --pbe= --pbe-millis=300 key") {}

      void go() override
         {
         std::unique_ptr<Botan::Private_Key> key;
         std::string pass_in = get_arg("pass-in");

         if (pass_in.empty())
         {
            key.reset(Botan::PKCS8::load_key(get_arg("key"), rng()));
         }
         else
         {
            key.reset(Botan::PKCS8::load_key(get_arg("key"), rng(), pass_in));
         }

         const std::chrono::milliseconds pbe_millis(get_arg_sz("pbe-millis"));
         const std::string pbe = get_arg("pbe");
         const bool der_out = flag_set("der-out");

         if(flag_set("pub-out"))
            {
            if(der_out)
               {
               write_output(Botan::X509::BER_encode(*key));
               }
            else
               {
               output() << Botan::X509::PEM_encode(*key);
               }
            }
         else
            {
            const std::string pass_out = get_arg("pass-out");

            if(der_out)
               {
               if(pass_out.empty())
                  {
                  write_output(Botan::PKCS8::BER_encode(*key));
                  }
               else
                  {
                  write_output(Botan::PKCS8::BER_encode(*key, rng(), pass_out, pbe_millis, pbe));
                  }
               }
            else
               {
               if(pass_out.empty())
                  {
                  output() << Botan::PKCS8::PEM_encode(*key);
                  }
               else
                  {
                  output() << Botan::PKCS8::PEM_encode(*key, rng(), pass_out, pbe_millis, pbe);
                  }
               }
            }
         }
   };

BOTAN_REGISTER_COMMAND("pkcs8", PKCS8_Tool);

}

#endif
<|endoftext|>


<commit_before>// $Id: residue.C,v 1.10 2000/04/27 15:09:34 amoll Exp $

#include <BALL/KERNEL/residue.h>

#include <BALL/KERNEL/chain.h>
#include <BALL/KERNEL/protein.h>
#include <BALL/STRUCTURE/geometricProperties.h>

using namespace std;

namespace BALL
{

	Residue::Residue()
		:	Fragment(),
			id_(BALL_RESIDUE_DEFAULT_ID),
			insertion_code_(BALL_RESIDUE_DEFAULT_INSERTION_CODE)
	{
	}

	Residue::Residue(const Residue& residue, bool deep)
		:	Fragment(residue, deep),
			id_(residue.id_),
			insertion_code_(residue.insertion_code_)
	{
	}

	Residue::Residue(const String& name, const String& id, char insertion_code)
		:	Fragment(name),
			id_(id),
			insertion_code_(insertion_code)
	{
	}

	Residue::~Residue()
	{
		destroy();
	}

	void Residue::clear()
	{
		Fragment::clear();

		clear_();
	}

	void Residue::destroy()
	{
		Fragment::destroy();

		clear_();
	}

	void Residue::persistentWrite(PersistenceManager& pm, const char* name) const
	{
		pm.writeObjectHeader(this, name);
			Fragment::persistentWrite(pm);
			pm.writePrimitive(id_, "id_");
			pm.writePrimitive(insertion_code_, "insertion_code_");
		pm.writeObjectTrailer(name);
	}

	void Residue::persistentRead(PersistenceManager& pm)
	{
		pm.checkObjectHeader(RTTI::getStreamName<Fragment>());
			Fragment::persistentRead(pm);
		pm.checkObjectTrailer(0);

		pm.readPrimitive(id_, "id_");
		pm.readPrimitive(insertion_code_, "insertion_code_");
	}

	void Residue::set(const Residue& residue, bool deep)
	{
		Fragment::set(residue, deep);

		id_ = residue.id_;
		insertion_code_ = residue.insertion_code_;
	}

	Residue& Residue::operator =(const Residue& residue)
	{
		set(residue);

		return *this;
	}

	void Residue::get(Residue& residue, bool deep) const
	{
		residue.set(*this, deep);
	}

	void Residue::swap(Residue& residue)
	{
		Fragment::swap(residue);

		id_.swap(residue.id_);

		char temp_insertion_code = insertion_code_;
		insertion_code_ = residue.insertion_code_;
		residue.insertion_code_ = temp_insertion_code;
	}

	bool Residue::hasTorsionPsi() const
	{
		// the torsion angle psi is not defined for
		// the C-terminus
		return !isCTerminal();
	}

	Angle Residue::getTorsionPsi() const
	{
		Angle result(0.0);
		if (hasTorsionPsi())
		{
			const Residue* next = getNext(RTTI::getDefault<Residue>());
			if (next != 0)
			{
				Atom* C = 0;
				Atom* N = 0;
				Atom* CA = 0;
				AtomIterator it;
				for (it = beginAtom(); +it; ++it)
				{
					if (it->getName() == "C")	C  = &*it;
					if (it->getName() == "CA") CA = &*it;
					if (it->getName() == "N")	N  = &*it;
				}

				Atom* next_N = 0;
				for (it = next->beginAtom(); +it; ++it)
				{
					if (it->getName() == "N")
					{
						next_N  = &*it;
						break;
					}
				}

				if ((N != 0) && (C != 0) && (CA != 0) && (next_N != 0))
				{
					result = calculateTorsionAngle(*N, *CA, *C, *next_N);
				}
				else
				{
					Log.error() << "Atoms not found:" << N << "/" << CA << "/" << C << "/" << next_N << endl;
				}
			}
			else
			{
				Log.error() << "No next residue!" << endl;
			}
		}

		return result;
	}

	bool Residue::hasTorsionPhi() const
	{
		// the torsion angle phi is not defined for
		// the C-terminus
		return !isNTerminal();
	}

	Angle Residue::getTorsionPhi() const
	{
		Angle result(0.0);
		if (hasTorsionPhi())
		{
			const Residue* previous = getPrevious(RTTI::getDefault<Residue>());
			if (previous != 0)
			{
				Atom* C = 0;
				Atom* N = 0;
				Atom* CA = 0;
				AtomIterator it;
				for (it = beginAtom(); +it; ++it)
				{
					if (it->getName() == "C")	 C  = &*it;
					if (it->getName() == "CA") CA = &*it;
					if (it->getName() == "N")  N  = &*it;
				}

				Atom* last_C = 0;
				for (it = previous->beginAtom(); +it; ++it)
				{
					if (it->getName() == "C")
					{
						last_C  = &*it;
						break;
					}
				}

				if ((N != 0) && (C != 0) && (CA != 0) && (last_C != 0))
				{
					result = calculateTorsionAngle(*last_C, *N, *CA, *C);
				}
				else
				{
					Log.error() << "Atoms not found:" << last_C << "/" << N << "/" << CA << "/" << C << endl;
				}
			}
			else
			{
				Log.error() << "No previous residue!" << endl;
			}
		}

		return result;
	}

	Protein* Residue::getProtein()
	{
		for (Composite::AncestorIterator ancestor_it = beginAncestor(); !ancestor_it.isEnd(); ++ancestor_it)
		{
			if (RTTI::isKindOf<Protein>(*ancestor_it))
			{
				return (Protein *)&*ancestor_it;
			}
		}

		return 0;
	}

	const Protein* Residue::getProtein() const
	{
		return ((Residue *)this)->getProtein();
	}

	Chain* Residue::getChain()
	{
		for (Composite::AncestorIterator ancestor_it = beginAncestor(); !ancestor_it.isEnd(); ++ancestor_it)
		{
			if (RTTI::isKindOf<Chain>(*ancestor_it))
			{
				return (Chain *)&*ancestor_it;
			}
		}

		return 0;
	}

	const Chain *Residue::getChain() const
	{
		return ((Residue *)this)->getChain();
	}

	PDBAtom *Residue::getPDBAtom(Position position)
	{
		for (PDBAtomIterator protein_atom_iterator = beginPDBAtom();
				 !protein_atom_iterator.isEnd(); ++protein_atom_iterator)
		{
			if (position-- == 0)
			{
				return &(*protein_atom_iterator);
			}
		}

		return 0;
	}

	const PDBAtom* Residue::getPDBAtom(Position position) const
	{
		return ((Residue *)this)->getPDBAtom(position);
	}

	void Residue::setID(const String &id)
	{
		id_ = id;
	}

	const String &Residue::getID() const
	{
		return id_;
	}

	void Residue::setInsertionCode(char insertion_code)
	{
		insertion_code_ = insertion_code;
	}

	char Residue::getInsertionCode() const
	{
		return insertion_code_;
	}

	Size Residue::countPDBAtoms() const
	{
		register Size size = 0;

		for (PDBAtomIterator protein_atom_iterator = beginPDBAtom();
				 !protein_atom_iterator.isEnd(); ++protein_atom_iterator)
		{
			++size;
		}

		return size;
	}

	void Residue::prepend(PDBAtom &protein_atom)
	{
		Fragment::prepend(protein_atom);
	}

	void Residue::append(PDBAtom& protein_atom)
	{
		Fragment::append(protein_atom);
	}

	void
	Residue::insert(PDBAtom& protein_atom)
	{
		Fragment::insert(protein_atom);
	}

	void Residue::insertBefore(PDBAtom& protein_atom, Composite& before)
	{
		Fragment::insertBefore(protein_atom, before);
	}

	void Residue::insertAfter(PDBAtom& protein_atom, Composite& after)
	{
		Fragment::insertAfter(protein_atom, after);
	}

	bool Residue::remove(PDBAtom& protein_atom)
	{
		return Fragment::remove(protein_atom);
	}

	void Residue::spliceBefore(Residue& residue)
	{
		Fragment::spliceBefore(residue);
	}

	void Residue::spliceAfter(Residue& residue)
	{
		Fragment::spliceAfter(residue);
	}

	void Residue::splice(Residue& residue)
	{
		Fragment::splice(residue);
	}

	bool Residue::isAminoAcid() const
	{
		return hasProperty(PROPERTY__AMINO_ACID);
	}

	bool Residue::isTerminal() const
	{
		return (isNTerminal() || isCTerminal());
	}

	bool Residue::isNTerminal() const
	{
		if (isAminoAcid() == true)
		{
			const Chain* chain = getChain();

			if (chain != 0)
			{
				ResidueConstIterator res_it = chain->beginResidue();
				for (; +res_it && &(*res_it) != this && !res_it->isAminoAcid(); ++res_it);

				return (&(*res_it) == this);
			}
		}

		return false;
	}

	bool Residue::isCTerminal() const
	{
		if (isAminoAcid() == true)
		{
			const Chain* chain = getChain();

			if (chain != 0)
			{
				ResidueConstIterator res_it = chain->rbeginResidue();
				for (; +res_it && &(*res_it) != this && !res_it->isAminoAcid(); --res_it);

				return (&(*res_it) == this);
			}
		}

		return false;
	}

	bool Residue::isValid() const
	{
		if (Fragment::isValid() == false
				|| id_.isValid() == false)
		{
			return false;
		}

		return true;
	}

	void Residue::dump(ostream& s, Size depth) const
	{
		BALL_DUMP_STREAM_PREFIX(s);

		Fragment::dump(s, depth);

		BALL_DUMP_DEPTH(s, depth);
		s << "  id: " << id_ << endl;

		BALL_DUMP_DEPTH(s, depth);
		s << "  insertion code: " << insertion_code_ << endl;

		BALL_DUMP_STREAM_SUFFIX(s);
	}

	void Residue::read(istream&  /* s */)
	{
		throw Exception::NotImplemented(__FILE__, __LINE__);
	}

	void Residue::write(ostream&  /*s */) const
	{
		throw Exception::NotImplemented(__FILE__, __LINE__);
	}

	void Residue::clear_()
	{
		id_ = BALL_RESIDUE_DEFAULT_ID;
		insertion_code_ = BALL_RESIDUE_DEFAULT_INSERTION_CODE;
	}

	String Residue::getFullName(Residue::FullNameType type) const
	{
		// retrieve the residue name and remove blanks
		String full_name = getName();
		full_name.trim();

		// if the variant extension should be added, do so
		if (type == ADD_VARIANT_EXTENSIONS)
		{
			String suffix = "-";
			if (isNTerminal())
			{
				suffix = "-N";
			}
			if (isCTerminal())
			{
				suffix = "-C";
			}
			if (isCTerminal() && isNTerminal())
			{
				suffix = "-M";
			}
			if (hasProperty(Residue::PROPERTY__HAS_SSBOND))
			{
				suffix += "S";
			}

			if (suffix != "-")
			{
				full_name += suffix;
			}
		}

		return full_name;
	}

} // namespace BALL
<commit_msg>fixed: hasTorsion***()<commit_after>// $Id: residue.C,v 1.11 2000/05/15 18:32:37 amoll Exp $

#include <BALL/KERNEL/residue.h>

#include <BALL/KERNEL/chain.h>
#include <BALL/KERNEL/protein.h>
#include <BALL/STRUCTURE/geometricProperties.h>

using namespace std;

namespace BALL
{

	Residue::Residue()
		:	Fragment(),
			id_(BALL_RESIDUE_DEFAULT_ID),
			insertion_code_(BALL_RESIDUE_DEFAULT_INSERTION_CODE)
	{
	}

	Residue::Residue(const Residue& residue, bool deep)
		:	Fragment(residue, deep),
			id_(residue.id_),
			insertion_code_(residue.insertion_code_)
	{
	}

	Residue::Residue(const String& name, const String& id, char insertion_code)
		:	Fragment(name),
			id_(id),
			insertion_code_(insertion_code)
	{
	}

	Residue::~Residue()
	{
		destroy();
	}

	void Residue::clear()
	{
		Fragment::clear();

		clear_();
	}

	void Residue::destroy()
	{
		Fragment::destroy();

		clear_();
	}

	void Residue::persistentWrite(PersistenceManager& pm, const char* name) const
	{
		pm.writeObjectHeader(this, name);
			Fragment::persistentWrite(pm);
			pm.writePrimitive(id_, "id_");
			pm.writePrimitive(insertion_code_, "insertion_code_");
		pm.writeObjectTrailer(name);
	}

	void Residue::persistentRead(PersistenceManager& pm)
	{
		pm.checkObjectHeader(RTTI::getStreamName<Fragment>());
			Fragment::persistentRead(pm);
		pm.checkObjectTrailer(0);

		pm.readPrimitive(id_, "id_");
		pm.readPrimitive(insertion_code_, "insertion_code_");
	}

	void Residue::set(const Residue& residue, bool deep)
	{
		Fragment::set(residue, deep);

		id_ = residue.id_;
		insertion_code_ = residue.insertion_code_;
	}

	Residue& Residue::operator =(const Residue& residue)
	{
		set(residue);

		return *this;
	}

	void Residue::get(Residue& residue, bool deep) const
	{
		residue.set(*this, deep);
	}

	void Residue::swap(Residue& residue)
	{
		Fragment::swap(residue);

		id_.swap(residue.id_);

		char temp_insertion_code = insertion_code_;
		insertion_code_ = residue.insertion_code_;
		residue.insertion_code_ = temp_insertion_code;
	}

	bool Residue::hasTorsionPsi() const
	{
		// instance must have a parent chain
		if (getChain() == 0)
		{
			return false;
		}
		// at least 2 residues are needed to create an angle
		if (getChain()->countResidues() < 2)
		{
			return false;
		}
		// the torsion angle psi is not defined for
		// the C-terminus
		return !isCTerminal();
	}

	Angle Residue::getTorsionPsi() const
	{
		Angle result(0.0);
		if (hasTorsionPsi())
		{
			const Residue* next = getNext(RTTI::getDefault<Residue>());
			if (next != 0)
			{
				Atom* C = 0;
				Atom* N = 0;
				Atom* CA = 0;
				AtomIterator it;
				for (it = beginAtom(); +it; ++it)
				{
					if (it->getName() == "C")	C  = &*it;
					if (it->getName() == "CA") CA = &*it;
					if (it->getName() == "N")	N  = &*it;
				}

				Atom* next_N = 0;
				for (it = next->beginAtom(); +it; ++it)
				{
					if (it->getName() == "N")
					{
						next_N  = &*it;
						break;
					}
				}

				if ((N != 0) && (C != 0) && (CA != 0) && (next_N != 0))
				{
					result = calculateTorsionAngle(*N, *CA, *C, *next_N);
				}
				else
				{
					Log.error() << "Atoms not found:" << N << "/" << CA << "/" << C << "/" << next_N << endl;
				}
			}
			else
			{
				Log.error() << "No next residue!" << endl;
			}
		}

		return result;
	}

	bool Residue::hasTorsionPhi() const
	{
		// instance must have a parent chain
		if (getChain() == 0)
		{
			return false;
		}
		// at least 2 residues are needed to create an angle
		if (getChain()->countResidues() < 2)
		{
			return false;
		}
		// the torsion angle phi is not defined for
		// the N-terminus
		return !isNTerminal();
	}

	Angle Residue::getTorsionPhi() const
	{
		Angle result(0.0);
		if (hasTorsionPhi())
		{
			const Residue* previous = getPrevious(RTTI::getDefault<Residue>());
			if (previous != 0)
			{
				Atom* C = 0;
				Atom* N = 0;
				Atom* CA = 0;
				AtomIterator it;
				for (it = beginAtom(); +it; ++it)
				{
					if (it->getName() == "C")	 C  = &*it;
					if (it->getName() == "CA") CA = &*it;
					if (it->getName() == "N")  N  = &*it;
				}

				Atom* last_C = 0;
				for (it = previous->beginAtom(); +it; ++it)
				{
					if (it->getName() == "C")
					{
						last_C  = &*it;
						break;
					}
				}

				if ((N != 0) && (C != 0) && (CA != 0) && (last_C != 0))
				{
					result = calculateTorsionAngle(*last_C, *N, *CA, *C);
				}
				else
				{
					Log.error() << "Atoms not found:" << last_C << "/" << N << "/" << CA << "/" << C << endl;
				}
			}
			else
			{
				Log.error() << "No previous residue!" << endl;
			}
		}

		return result;
	}

	Protein* Residue::getProtein()
	{
		for (Composite::AncestorIterator ancestor_it = beginAncestor(); !ancestor_it.isEnd(); ++ancestor_it)
		{
			if (RTTI::isKindOf<Protein>(*ancestor_it))
			{
				return (Protein *)&*ancestor_it;
			}
		}

		return 0;
	}

	const Protein* Residue::getProtein() const
	{
		return ((Residue *)this)->getProtein();
	}

	Chain* Residue::getChain()
	{
		for (Composite::AncestorIterator ancestor_it = beginAncestor(); !ancestor_it.isEnd(); ++ancestor_it)
		{
			if (RTTI::isKindOf<Chain>(*ancestor_it))
			{
				return (Chain *)&*ancestor_it;
			}
		}

		return 0;
	}

	const Chain *Residue::getChain() const
	{
		return ((Residue *)this)->getChain();
	}

	PDBAtom *Residue::getPDBAtom(Position position)
	{
		for (PDBAtomIterator protein_atom_iterator = beginPDBAtom();
				 !protein_atom_iterator.isEnd(); ++protein_atom_iterator)
		{
			if (position-- == 0)
			{
				return &(*protein_atom_iterator);
			}
		}

		return 0;
	}

	const PDBAtom* Residue::getPDBAtom(Position position) const
	{
		return ((Residue *)this)->getPDBAtom(position);
	}

	void Residue::setID(const String &id)
	{
		id_ = id;
	}

	const String &Residue::getID() const
	{
		return id_;
	}

	void Residue::setInsertionCode(char insertion_code)
	{
		insertion_code_ = insertion_code;
	}

	char Residue::getInsertionCode() const
	{
		return insertion_code_;
	}

	Size Residue::countPDBAtoms() const
	{
		register Size size = 0;

		for (PDBAtomIterator protein_atom_iterator = beginPDBAtom();
				 !protein_atom_iterator.isEnd(); ++protein_atom_iterator)
		{
			++size;
		}

		return size;
	}

	void Residue::prepend(PDBAtom &protein_atom)
	{
		Fragment::prepend(protein_atom);
	}

	void Residue::append(PDBAtom& protein_atom)
	{
		Fragment::append(protein_atom);
	}

	void
	Residue::insert(PDBAtom& protein_atom)
	{
		Fragment::insert(protein_atom);
	}

	void Residue::insertBefore(PDBAtom& protein_atom, Composite& before)
	{
		Fragment::insertBefore(protein_atom, before);
	}

	void Residue::insertAfter(PDBAtom& protein_atom, Composite& after)
	{
		Fragment::insertAfter(protein_atom, after);
	}

	bool Residue::remove(PDBAtom& protein_atom)
	{
		return Fragment::remove(protein_atom);
	}

	void Residue::spliceBefore(Residue& residue)
	{
		Fragment::spliceBefore(residue);
	}

	void Residue::spliceAfter(Residue& residue)
	{
		Fragment::spliceAfter(residue);
	}

	void Residue::splice(Residue& residue)
	{
		Fragment::splice(residue);
	}

	bool Residue::isAminoAcid() const
	{
		return hasProperty(PROPERTY__AMINO_ACID);
	}

	bool Residue::isTerminal() const
	{
		return (isNTerminal() || isCTerminal());
	}

	bool Residue::isNTerminal() const
	{
		if (isAminoAcid() == true)
		{
			const Chain* chain = getChain();

			if (chain != 0)
			{
				ResidueConstIterator res_it = chain->beginResidue();
				for (; +res_it && &(*res_it) != this && !res_it->isAminoAcid(); ++res_it);

				return (&(*res_it) == this);
			}
		}

		return false;
	}

	bool Residue::isCTerminal() const
	{
		if (isAminoAcid() == true)
		{
			const Chain* chain = getChain();

			if (chain != 0)
			{
				ResidueConstIterator res_it = chain->rbeginResidue();
				for (; +res_it && &(*res_it) != this && !res_it->isAminoAcid(); --res_it);

				return (&(*res_it) == this);
			}
		}

		return false;
	}

	bool Residue::isValid() const
	{
		if (Fragment::isValid() == false
				|| id_.isValid() == false)
		{
			return false;
		}

		return true;
	}

	void Residue::dump(ostream& s, Size depth) const
	{
		BALL_DUMP_STREAM_PREFIX(s);

		Fragment::dump(s, depth);

		BALL_DUMP_DEPTH(s, depth);
		s << "  id: " << id_ << endl;

		BALL_DUMP_DEPTH(s, depth);
		s << "  insertion code: " << insertion_code_ << endl;

		BALL_DUMP_STREAM_SUFFIX(s);
	}

	void Residue::read(istream&  /* s */)
	{
		throw Exception::NotImplemented(__FILE__, __LINE__);
	}

	void Residue::write(ostream&  /*s */) const
	{
		throw Exception::NotImplemented(__FILE__, __LINE__);
	}

	void Residue::clear_()
	{
		id_ = BALL_RESIDUE_DEFAULT_ID;
		insertion_code_ = BALL_RESIDUE_DEFAULT_INSERTION_CODE;
	}

	String Residue::getFullName(Residue::FullNameType type) const
	{
		// retrieve the residue name and remove blanks
		String full_name = getName();
		full_name.trim();

		// if the variant extension should be added, do so
		if (type == ADD_VARIANT_EXTENSIONS)
		{
			String suffix = "-";
			if (isNTerminal())
			{
				suffix = "-N";
			}
			if (isCTerminal())
			{
				suffix = "-C";
			}
			if (isCTerminal() && isNTerminal())
			{
				suffix = "-M";
			}
			if (hasProperty(Residue::PROPERTY__HAS_SSBOND))
			{
				suffix += "S";
			}

			if (suffix != "-")
			{
				full_name += suffix;
			}
		}

		return full_name;
	}

} // namespace BALL
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: sysinfo.C,v 1.11 2005/03/01 07:33:10 oliver Exp $
//

#include <BALL/SYSTEM/sysinfo.h>

#ifdef BALL_HAS_SYS_SYSINFO_H
#	include <sys/sysinfo.h>
#	include <BALL/SYSTEM/file.h>
#else
# ifdef BALL_PLATFORM_WINDOWS
#	  define WIN32_LEAN_AND_MEAN
#	  include <windows.h>
# endif
# ifdef BALL_PLATFORM_DARWIN
#  include <sys/sysctl.h>
#	endif
#endif

namespace BALL
{
	namespace SysInfo
	{

#ifdef BALL_HAS_SYS_SYSINFO_H

		LongIndex getAvailableMemory()
		{
			LongIndex mem = getFreeMemory();
			return mem;
		}

		LongIndex getFreeMemory()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1)
			{
				return result;
			}
			return info.freeram * info.mem_unit;
		}

		LongIndex getTotalMemory()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1)
			{
				return result;
			}
			return info.totalram * info.mem_unit;
		}

		LongIndex getBufferedMemory()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1) return result;
			return info.bufferram * info.mem_unit;
		}

		Time getUptime()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1) return result;
			return info.uptime;
		}

		Index getNumberOfProcessors()
		{
			return get_nprocs();
		}

		LongIndex getFreeSwapSpace()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1) return result;
			return info.freeswap * info.mem_unit;
		}
#else
#ifdef BALL_PLATFORM_WINDOWS

		LongIndex getAvailableMemory()
		{
			return getFreememory();
		}

		LongIndex getFreeMemory()
		{
			MEMORYSTATUSEX statex;
			GlobalMemoryStatusEx (&statex);
			return static_cast<LongIndex>(statex.ullAvailPhys);
		}

		LongIndex getTotalMemory()
		{
 			MEMORYSTATUSEX statex;
			GlobalMemoryStatusEx (&statex);
			return static_cast<LongIndex>(statex.ullTotalPhys);
		}

		LongIndex getBufferedMemory()
		{
			return 0;
		}

		Time getUptime()
		{
			return -1;
		}

		Index getNumberOfProcessors()
		{
			SYSTEM_INFO sysinfo;
			GetSystemInfo(&sysinfo);
			return sysinfo.dwNumberOfProcessors;
		}

		LongIndex getFreeSwapSpace()
		{
 			MEMORYSTATUSEX statex;
			GlobalMemoryStatusEx (&statex);
			return (LongIndex) statex.ullAvailPageFile;
		}

#else // We have no idea how to retrieve that information on this
			// platform, so we just return -1 everywhere

		LongIndex getAvailableMemory()
		{
			LongIndex mem = getFreeMemory();
			return mem;
		}

		LongIndex getFreeMemory()
		{
			return -1;
		}

		LongIndex getTotalMemory()
		{
			return -1;
		}

		LongIndex getBufferedMemory()
		{
			return -1;
		}

		Time getUptime()
		{
			return -1;
		}

		Index getNumberOfProcessors()
		{
			return -1;
		}

		LongIndex getFreeSwapSpace()
		{
			return -1;
		}

#endif
#endif

	} // namespace SysInfo

} // namespace BALL

<commit_msg>*** empty log message ***<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//
// $Id: sysinfo.C,v 1.12 2005/03/01 08:14:49 oliver Exp $
//

#include <BALL/SYSTEM/sysinfo.h>

#ifdef BALL_HAS_SYS_SYSINFO_H
#	include <sys/sysinfo.h>
#	include <BALL/SYSTEM/file.h>
#else
# ifdef BALL_PLATFORM_WINDOWS
#	  define WIN32_LEAN_AND_MEAN
#	  include <windows.h>
# endif
# ifdef BALL_PLATFORM_DARWIN
#  include <sys/sysctl.h>
#	endif
#endif

namespace BALL
{
	namespace SysInfo
	{

#ifdef BALL_HAS_SYS_SYSINFO_H

		LongIndex getAvailableMemory()
		{
			LongIndex mem = getFreeMemory();
			return mem;
		}

		LongIndex getFreeMemory()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1)
			{
				return result;
			}
			return info.freeram * info.mem_unit;
		}

		LongIndex getTotalMemory()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1)
			{
				return result;
			}
			return info.totalram * info.mem_unit;
		}

		LongIndex getBufferedMemory()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1) return result;
			return info.bufferram * info.mem_unit;
		}

		Time getUptime()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1) return result;
			return info.uptime;
		}

		Index getNumberOfProcessors()
		{
			return get_nprocs();
		}

		LongIndex getFreeSwapSpace()
		{
			struct sysinfo info;
			LongIndex result = sysinfo(&info);
			if (result == -1) return result;
			return info.freeswap * info.mem_unit;
		}
#else
#ifdef BALL_PLATFORM_WINDOWS

		LongIndex getAvailableMemory()
		{
			return getFreememory();
		}

		LongIndex getFreeMemory()
		{
			MEMORYSTATUSEX statex;
			GlobalMemoryStatusEx (&statex);
			return static_cast<LongIndex>(statex.ullAvailPhys);
		}

		LongIndex getTotalMemory()
		{
 			MEMORYSTATUSEX statex;
			GlobalMemoryStatusEx (&statex);
			return static_cast<LongIndex>(statex.ullTotalPhys);
		}

		LongIndex getBufferedMemory()
		{
			return 0;
		}

		Time getUptime()
		{
			return -1;
		}

		Index getNumberOfProcessors()
		{
			SYSTEM_INFO sysinfo;
			GetSystemInfo(&sysinfo);
			return sysinfo.dwNumberOfProcessors;
		}

		LongIndex getFreeSwapSpace()
		{
 			MEMORYSTATUSEX statex;
			GlobalMemoryStatusEx (&statex);
			return (LongIndex) statex.ullAvailPageFile;
		}

#else
#ifdef BALL_PLATFORM_DARWIN

		LongIndex getAvailableMemory()
		{
			LongIndex mem = getFreeMemory();
			return mem;
		}

		LongIndex getFreeMemory()
		{
			return -1;
		}

		LongIndex getTotalMemory()
		{
			return -1;
		}

		LongIndex getBufferedMemory()
		{
			return -1;
		}

		Time getUptime()
		{
			return -1;
		}

		Index getNumberOfProcessors()
		{
			int mib[2] = { CTL_HW, HW_NCPU };
			int num_proc = 0;
			size_t len = sizeof(num_proc);
			sysctl(mib, 2, &num_proc, &len, NULL, 0);
			return (Index)num_proc;
		}

		LongIndex getFreeSwapSpace()
		{
			return -1;
		}

#else // We have no idea how to retrieve that information on this
			// platform, so we just return -1 everywhere

		LongIndex getAvailableMemory()
		{
			return -1
		}

		LongIndex getFreeMemory()
		{
			return -1;
		}

		LongIndex getTotalMemory()
		{
			return -1;
		}

		LongIndex getBufferedMemory()
		{
			return -1;
		}

		Time getUptime()
		{
			return -1;
		}

		Index getNumberOfProcessors()
		{
			return -1;
		}

#endif
#endif
#endif

	} // namespace SysInfo

} // namespace BALL

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <uavcan_stm32/thread.hpp>
#include <uavcan_stm32/clock.hpp>
#include <uavcan_stm32/can.hpp>
#include "internal.hpp"

namespace uavcan_stm32
{

#if UAVCAN_STM32_CHIBIOS
/*
 * BusEvent
 */
bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
    static const uavcan::int64_t MaxDelayMSec = 0x000FFFFF;

    const uavcan::int64_t msec = duration.toMSec();
    msg_t ret = msg_t();

    if (msec <= 0)
    {
# if (CH_KERNEL_MAJOR == 2)
        ret = sem_.waitTimeout(TIME_IMMEDIATE);
# else // ChibiOS 3+
        ret = sem_.wait(TIME_IMMEDIATE);
# endif
    }
    else
    {
# if (CH_KERNEL_MAJOR == 2)
        ret = sem_.waitTimeout((msec > MaxDelayMSec) ? MS2ST(MaxDelayMSec) : MS2ST(msec));
# else // ChibiOS 3+
        ret = sem_.wait((msec > MaxDelayMSec) ? MS2ST(MaxDelayMSec) : MS2ST(msec));
# endif
    }
# if (CH_KERNEL_MAJOR == 2)
    return ret == RDY_OK;
# else // ChibiOS 3+
    return ret == MSG_OK;
# endif
}

void BusEvent::signal()
{
    sem_.signal();
}

void BusEvent::signalFromInterrupt()
{
# if (CH_KERNEL_MAJOR == 2)
    chSysLockFromIsr();
    sem_.signalI();
    chSysUnlockFromIsr();
# else // ChibiOS 3+
    chSysLockFromISR();
    sem_.signalI();
    chSysUnlockFromISR();
# endif
}

/*
 * Mutex
 */
void Mutex::lock()
{
    mtx_.lock();
}

void Mutex::unlock()
{
# if (CH_KERNEL_MAJOR == 2)
    chibios_rt::BaseThread::unlockMutex();
# else // ChibiOS 3+
    mtx_.unlock();
# endif
}

#elif UAVCAN_STM32_FREERTOS

bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
    static const uavcan::int64_t MaxDelayMSec = 0x000FFFFF;

    const uavcan::int64_t msec = duration.toMSec();

    BaseType_t ret;

    if (msec <= 0)
    {
        ret = xSemaphoreTake( sem_, ( TickType_t ) 0 );
    }
    else
    {
        ret = xSemaphoreTake( sem_, (msec > MaxDelayMSec) ? (MaxDelayMSec/portTICK_RATE_MS) : (msec/portTICK_RATE_MS));
    }
    return ret == pdTRUE;
}

void BusEvent::signal()
{
    xSemaphoreGive( sem_ );
}

void BusEvent::signalFromInterrupt()
{
    higher_priority_task_woken = pdFALSE;

    xSemaphoreGiveFromISR( sem_, &higher_priority_task_woken );
}

void BusEvent::yieldFromISR()
{
    portYIELD_FROM_ISR( higher_priority_task_woken );
}

/*
 * Mutex
 */
void Mutex::lock()
{
    xSemaphoreTake( mtx_, portMAX_DELAY );
}

void Mutex::unlock()
{
    xSemaphoreGive( mtx_ );
}

#elif UAVCAN_STM32_NUTTX

const unsigned BusEvent::MaxPollWaiters;
const char* const BusEvent::DevName = "/dev/uavcan/busevent";

int BusEvent::openTrampoline(::file* filp)
{
    return static_cast<BusEvent*>(filp->f_inode->i_private)->open(filp);
}

int BusEvent::closeTrampoline(::file* filp)
{
    return static_cast<BusEvent*>(filp->f_inode->i_private)->close(filp);
}

int BusEvent::pollTrampoline(::file* filp, ::pollfd* fds, bool setup)
{
    return static_cast<BusEvent*>(filp->f_inode->i_private)->poll(filp, fds, setup);
}

int BusEvent::open(::file* filp)
{
    (void)filp;
    return 0;
}

int BusEvent::close(::file* filp)
{
    (void)filp;
    return 0;
}

int BusEvent::poll(::file* filp, ::pollfd* fds, bool setup)
{
    CriticalSectionLocker locker;
    int ret = -1;

    if (setup)
    {
        ret = addPollWaiter(fds);
        if (ret == 0)
        {
            /*
             * Two events can be reported via POLLIN:
             *  - The RX queue is not empty. This event is level-triggered.
             *  - Transmission complete. This event is edge-triggered.
             * FIXME Since TX event is edge-triggered, it can be lost between poll() calls.
             */
            fds->revents |= fds->events & (can_driver_.hasReadableInterfaces() ? POLLIN : 0);
            if (fds->revents != 0)
            {
                (void)sem_post(fds->sem);
            }
        }
    }
    else
    {
        ret = removePollWaiter(fds);
    }

    return ret;
}

int BusEvent::addPollWaiter(::pollfd* fds)
{
    for (unsigned i = 0; i < MaxPollWaiters; i++)
    {
        if (pollset_[i] == UAVCAN_NULLPTR)
        {
            pollset_[i] = fds;
            return 0;
        }
    }
    return -ENOMEM;
}

int BusEvent::removePollWaiter(::pollfd* fds)
{
    for (unsigned i = 0; i < MaxPollWaiters; i++)
    {
        if (fds == pollset_[i])
        {
            pollset_[i] = UAVCAN_NULLPTR;
            return 0;
        }
    }
    return -EINVAL;
}

BusEvent::BusEvent(CanDriver& can_driver)
    : can_driver_(can_driver)
    , signal_(false)
{
    std::memset(&file_ops_, 0, sizeof(file_ops_));
    std::memset(pollset_, 0, sizeof(pollset_));
    file_ops_.open  = &BusEvent::openTrampoline;
    file_ops_.close = &BusEvent::closeTrampoline;
    file_ops_.poll  = &BusEvent::pollTrampoline;
    // TODO: move to init(), add proper error handling
    if (register_driver(DevName, &file_ops_, 0666, static_cast<void*>(this)) != 0)
    {
        std::abort();
    }
}

BusEvent::~BusEvent()
{
    (void)unregister_driver(DevName);
}

bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
    // TODO blocking wait
    const uavcan::MonotonicTime deadline = clock::getMonotonic() + duration;
    while (clock::getMonotonic() < deadline)
    {
        {
            CriticalSectionLocker locker;
            if (signal_)
            {
                signal_ = false;
                return true;
            }
        }
        ::usleep(1000);
    }
    return false;
}

void BusEvent::signalFromInterrupt()
{
    signal_ = true;  // HACK
    for (unsigned i = 0; i < MaxPollWaiters; i++)
    {
        ::pollfd* const fd = pollset_[i];
        if (fd != UAVCAN_NULLPTR)
        {
            fd->revents |= fd->events & POLLIN;
            if ((fd->revents != 0) && (fd->sem->semcount <= 0))
            {
                (void)sem_post(fd->sem);
            }
        }
    }
}

#endif

}
<commit_msg>stm32: allow for less than 1ms wait time<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <uavcan_stm32/thread.hpp>
#include <uavcan_stm32/clock.hpp>
#include <uavcan_stm32/can.hpp>
#include "internal.hpp"

namespace uavcan_stm32
{

#if UAVCAN_STM32_CHIBIOS
/*
 * BusEvent
 */
bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
    // set maximum time to allow for 16 bit timers running at 1MHz
    static const uavcan::int64_t MaxDelayUSec = 0x000FFFF;

    const uavcan::int64_t usec = duration.toUSec();
    msg_t ret = msg_t();

    if (usec <= 0)
    {
# if (CH_KERNEL_MAJOR == 2)
        ret = sem_.waitTimeout(TIME_IMMEDIATE);
# else // ChibiOS 3+
        ret = sem_.wait(TIME_IMMEDIATE);
# endif
    }
    else
    {
# if (CH_KERNEL_MAJOR == 2)
        ret = sem_.waitTimeout((usec > MaxDelayUSec) ? US2ST(MaxDelayUSec) : US2ST(usec));
# else // ChibiOS 3+
        ret = sem_.wait((usec > MaxDelayUSec) ? US2ST(MaxDelayUSec) : US2ST(usec));
# endif
    }
# if (CH_KERNEL_MAJOR == 2)
    return ret == RDY_OK;
# else // ChibiOS 3+
    return ret == MSG_OK;
# endif
}

void BusEvent::signal()
{
    sem_.signal();
}

void BusEvent::signalFromInterrupt()
{
# if (CH_KERNEL_MAJOR == 2)
    chSysLockFromIsr();
    sem_.signalI();
    chSysUnlockFromIsr();
# else // ChibiOS 3+
    chSysLockFromISR();
    sem_.signalI();
    chSysUnlockFromISR();
# endif
}

/*
 * Mutex
 */
void Mutex::lock()
{
    mtx_.lock();
}

void Mutex::unlock()
{
# if (CH_KERNEL_MAJOR == 2)
    chibios_rt::BaseThread::unlockMutex();
# else // ChibiOS 3+
    mtx_.unlock();
# endif
}

#elif UAVCAN_STM32_FREERTOS

bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
    static const uavcan::int64_t MaxDelayMSec = 0x000FFFFF;

    const uavcan::int64_t msec = duration.toMSec();

    BaseType_t ret;

    if (msec <= 0)
    {
        ret = xSemaphoreTake( sem_, ( TickType_t ) 0 );
    }
    else
    {
        ret = xSemaphoreTake( sem_, (msec > MaxDelayMSec) ? (MaxDelayMSec/portTICK_RATE_MS) : (msec/portTICK_RATE_MS));
    }
    return ret == pdTRUE;
}

void BusEvent::signal()
{
    xSemaphoreGive( sem_ );
}

void BusEvent::signalFromInterrupt()
{
    higher_priority_task_woken = pdFALSE;

    xSemaphoreGiveFromISR( sem_, &higher_priority_task_woken );
}

void BusEvent::yieldFromISR()
{
    portYIELD_FROM_ISR( higher_priority_task_woken );
}

/*
 * Mutex
 */
void Mutex::lock()
{
    xSemaphoreTake( mtx_, portMAX_DELAY );
}

void Mutex::unlock()
{
    xSemaphoreGive( mtx_ );
}

#elif UAVCAN_STM32_NUTTX

const unsigned BusEvent::MaxPollWaiters;
const char* const BusEvent::DevName = "/dev/uavcan/busevent";

int BusEvent::openTrampoline(::file* filp)
{
    return static_cast<BusEvent*>(filp->f_inode->i_private)->open(filp);
}

int BusEvent::closeTrampoline(::file* filp)
{
    return static_cast<BusEvent*>(filp->f_inode->i_private)->close(filp);
}

int BusEvent::pollTrampoline(::file* filp, ::pollfd* fds, bool setup)
{
    return static_cast<BusEvent*>(filp->f_inode->i_private)->poll(filp, fds, setup);
}

int BusEvent::open(::file* filp)
{
    (void)filp;
    return 0;
}

int BusEvent::close(::file* filp)
{
    (void)filp;
    return 0;
}

int BusEvent::poll(::file* filp, ::pollfd* fds, bool setup)
{
    CriticalSectionLocker locker;
    int ret = -1;

    if (setup)
    {
        ret = addPollWaiter(fds);
        if (ret == 0)
        {
            /*
             * Two events can be reported via POLLIN:
             *  - The RX queue is not empty. This event is level-triggered.
             *  - Transmission complete. This event is edge-triggered.
             * FIXME Since TX event is edge-triggered, it can be lost between poll() calls.
             */
            fds->revents |= fds->events & (can_driver_.hasReadableInterfaces() ? POLLIN : 0);
            if (fds->revents != 0)
            {
                (void)sem_post(fds->sem);
            }
        }
    }
    else
    {
        ret = removePollWaiter(fds);
    }

    return ret;
}

int BusEvent::addPollWaiter(::pollfd* fds)
{
    for (unsigned i = 0; i < MaxPollWaiters; i++)
    {
        if (pollset_[i] == UAVCAN_NULLPTR)
        {
            pollset_[i] = fds;
            return 0;
        }
    }
    return -ENOMEM;
}

int BusEvent::removePollWaiter(::pollfd* fds)
{
    for (unsigned i = 0; i < MaxPollWaiters; i++)
    {
        if (fds == pollset_[i])
        {
            pollset_[i] = UAVCAN_NULLPTR;
            return 0;
        }
    }
    return -EINVAL;
}

BusEvent::BusEvent(CanDriver& can_driver)
    : can_driver_(can_driver)
    , signal_(false)
{
    std::memset(&file_ops_, 0, sizeof(file_ops_));
    std::memset(pollset_, 0, sizeof(pollset_));
    file_ops_.open  = &BusEvent::openTrampoline;
    file_ops_.close = &BusEvent::closeTrampoline;
    file_ops_.poll  = &BusEvent::pollTrampoline;
    // TODO: move to init(), add proper error handling
    if (register_driver(DevName, &file_ops_, 0666, static_cast<void*>(this)) != 0)
    {
        std::abort();
    }
}

BusEvent::~BusEvent()
{
    (void)unregister_driver(DevName);
}

bool BusEvent::wait(uavcan::MonotonicDuration duration)
{
    // TODO blocking wait
    const uavcan::MonotonicTime deadline = clock::getMonotonic() + duration;
    while (clock::getMonotonic() < deadline)
    {
        {
            CriticalSectionLocker locker;
            if (signal_)
            {
                signal_ = false;
                return true;
            }
        }
        ::usleep(1000);
    }
    return false;
}

void BusEvent::signalFromInterrupt()
{
    signal_ = true;  // HACK
    for (unsigned i = 0; i < MaxPollWaiters; i++)
    {
        ::pollfd* const fd = pollset_[i];
        if (fd != UAVCAN_NULLPTR)
        {
            fd->revents |= fd->events & POLLIN;
            if ((fd->revents != 0) && (fd->sem->semcount <= 0))
            {
                (void)sem_post(fd->sem);
            }
        }
    }
}

#endif

}
<|endoftext|>


<commit_before>//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#include "pch.h"
#include "shared_macros.h"
#include "xsapi/services.h"
#include "user_context.h"
#include "xbox_system_factory.h"
#include "xsapi/system.h"
#include "xbox_live_context_impl.h"
#if !TV_API && !UNIT_TEST_SERVICES && !XSAPI_SERVER
#include "notification_service.h"
#endif
#include "presence_internal.h"
#include "real_time_activity_internal.h"

NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN

#if TV_API | XBOX_UWP

xbox_live_context_impl::xbox_live_context_impl(
    _In_ Windows::Xbox::System::User^ user
    ) :
    m_signInContext(0),
    m_signOutContext(0)
{
    m_userContext = std::make_shared<xbox::services::user_context>(user);
}

Windows::Xbox::System::User^
xbox_live_context_impl::user()
{
    return m_userContext->user();
}

#else

xbox_live_context_impl::xbox_live_context_impl(
    _In_ std::shared_ptr<system::xbox_live_user> user
    ) :
    m_signInContext(0),
    m_signOutContext(0)
{
    user->_User_impl()->set_user_pointer(user);
    m_userContext = std::make_shared<xbox::services::user_context>(user);
}

#if XSAPI_CPP
std::shared_ptr<system::xbox_live_user>
xbox_live_context_impl::user()
{
    return m_userContext->user();
}

#else
xbox_live_context_impl::xbox_live_context_impl(
    _In_ Microsoft::Xbox::Services::System::XboxLiveUser^ user
    ) :
    m_signInContext(0),
    m_signOutContext(0)
{
    m_userContext = std::make_shared<xbox::services::user_context>(user);
}

Microsoft::Xbox::Services::System::XboxLiveUser^
xbox_live_context_impl::user()
{
    return m_userContext->user();
}
#endif
#endif

xbox_live_context_impl::~xbox_live_context_impl()
{
    if (m_userContext->user() != nullptr)
    {
#if !TV_API && !UNIT_TEST_SERVICES && !XSAPI_SERVER
#if XSAPI_CPP
        m_userContext->user()->_User_impl()->remove_sign_in_completed_handler(
            m_signInContext
            );

        m_userContext->user()->_User_impl()->remove_sign_out_completed_handler(
            m_signOutContext
            );
#else
        m_userContext->user()->GetUserImpl()->remove_sign_in_completed_handler(
            m_signInContext
            );

        m_userContext->user()->GetUserImpl()->remove_sign_out_completed_handler(
            m_signOutContext
            );
#endif
#endif
    }

    real_time_activity::real_time_activity_service_factory::get_singleton_instance()->remove_user_from_rta_map(m_userContext);
}

void xbox_live_context_impl::init()
{
    xbox_live_result<void> servicesConfigFileReadResult;

    m_appConfig = xbox_live_app_config::get_app_config_singleton();
    m_xboxLiveContextSettings = std::make_shared<xbox::services::xbox_live_context_settings>();
    init_real_time_activity_service_instance();

#if TV_API || UWP_API
    auto mainView = Windows::ApplicationModel::Core::CoreApplication::MainView;
    if (mainView != nullptr)
    {
        auto coreWindow = mainView->CoreWindow;
        if (coreWindow != nullptr)
        {
            auto dispatcher = coreWindow->Dispatcher;
            if (dispatcher != nullptr)
            {
                dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
                    ref new Windows::UI::Core::DispatchedHandler([]()
                {
                    xbox::services::service_call_logging_config::get_singleton_instance()->_Register_for_protocol_activation();
                }));
            }
        }
    }

    xbox::services::service_call_logging_config::get_singleton_instance()->_ReadLocalConfig();

#endif

    std::weak_ptr<xbox_live_context_impl> thisWeakPtr = shared_from_this();

    m_profileService = xbox::services::social::profile_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_reputationService = xbox::services::social::reputation_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_leaderboardService = xbox::services::leaderboard::leaderboard_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_achievementService = xbox::services::achievements::achievement_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, thisWeakPtr);
    m_matchmakingService = xbox::services::matchmaking::matchmaking_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_gameServerPlatformService = xbox::services::game_server_platform::game_server_platform_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_titleStorageService = xbox::services::title_storage::title_storage_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_privacyService = xbox::services::privacy::privacy_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_presenceService = xbox::services::presence::presence_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_userStatisticsService = xbox::services::user_statistics::user_statistics_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_multiplayerService = xbox::services::multiplayer::multiplayer_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_socialService = xbox::services::social::social_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_stringService = xbox::services::system::string_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_contextualSearchService = xbox::services::contextual_search::contextual_search_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);

#if !XSAPI_SERVER

#if UWP_API || XSAPI_U
    m_eventsService = events::events_service(m_userContext, m_appConfig);
#endif

#if TV_API || UNIT_TEST_SERVICES
    // These services are only on XDK
    m_catalogService = marketplace::catalog_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_inventoryService = marketplace::inventory_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_entertainmentProfileService = entertainment_profile::entertainment_profile_list_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
#else

#if !XBOX_UWP

    // Only start the presence writer on UAP
    presence::presence_writer::get_presence_writer_singleton()->start_writer(m_presenceService._Impl());

    auto notificationService = notification::notification_service::get_notification_service_singleton();
    notificationService->subscribe_to_notifications(
        m_userContext,
        m_xboxLiveContextSettings,
        m_appConfig
        );

    if (m_userContext->user() != nullptr)
    {
#if !TV_API && XSAPI_CPP
        m_signInContext = m_userContext->user()->_User_impl()->add_sign_in_completed_handler(
        [thisWeakPtr](const string_t& xboxUserId)
        {
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr && utils::str_icmp(pThis->xbox_live_user_id(), xboxUserId) == 0)
            {
                presence::presence_writer::get_presence_writer_singleton()->start_writer(pThis->m_presenceService._Impl());
            }
        });

        m_signOutContext = m_userContext->user()->_User_impl()->add_sign_out_completed_handler(
            [thisWeakPtr](const system::sign_out_completed_event_args& args)
        {
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr)
            {
                pThis->real_time_activity_service()->_Close_websocket();
                presence::presence_writer::get_presence_writer_singleton()->stop_writer(pThis->xbox_live_user_id());
            }
        });

#elif !TV_API
        m_signInContext = m_userContext->user()->GetUserImpl()->add_sign_in_completed_handler(
            [thisWeakPtr](const string_t& xboxUserId)
        {
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr && utils::str_icmp(pThis->xbox_live_user_id(), xboxUserId) == 0)
            {
                presence::presence_writer::get_presence_writer_singleton()->start_writer(pThis->m_presenceService._Impl());
            }
        });

        m_signOutContext = m_userContext->user()->GetUserImpl()->add_sign_out_completed_handler(
                [thisWeakPtr](const system::sign_out_completed_event_args& args)
        {
            UNREFERENCED_PARAMETER(args);
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr)
            {
                pThis->real_time_activity_service()->_Close_websocket();
                presence::presence_writer::get_presence_writer_singleton()->stop_writer(pThis->xbox_live_user_id());
            }
        });
#endif
    }
#endif
#endif
#endif
}

std::shared_ptr<user_context> xbox_live_context_impl::user_context()
{
    return m_userContext;
}

const string_t& xbox_live_context_impl::xbox_live_user_id()
{
    return m_userContext->xbox_user_id();
}

social::profile_service&
xbox_live_context_impl::profile_service()
{
    return m_profileService;
}

social::social_service&
xbox_live_context_impl::social_service()
{
    return m_socialService;
}

social::reputation_service&
xbox_live_context_impl::reputation_service()
{
    return m_reputationService;
}

leaderboard::leaderboard_service&
xbox_live_context_impl::leaderboard_service()
{
    return m_leaderboardService;
}

achievements::achievement_service&
xbox_live_context_impl::achievement_service()
{
    return m_achievementService;
}

multiplayer::multiplayer_service&
xbox_live_context_impl::multiplayer_service()
{
    return m_multiplayerService;
}

matchmaking::matchmaking_service&
xbox_live_context_impl::matchmaking_service()
{
    return m_matchmakingService;
}

user_statistics::user_statistics_service&
xbox_live_context_impl::user_statistics_service()
{
    return m_userStatisticsService;
}

void
xbox_live_context_impl::init_real_time_activity_service_instance()
{
    if (m_userContext->caller_context_type() == caller_context_type::title)
    {
        m_realTimeActivityService = std::shared_ptr<xbox::services::real_time_activity::real_time_activity_service>(new xbox::services::real_time_activity::real_time_activity_service(m_userContext, m_xboxLiveContextSettings, m_appConfig));
    }
    else
    {
        m_realTimeActivityService = real_time_activity::real_time_activity_service_factory::get_singleton_instance()->get_rta_instance(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    }
}

const std::shared_ptr<real_time_activity::real_time_activity_service>&
xbox_live_context_impl::real_time_activity_service()
{
    return m_realTimeActivityService;
}

presence::presence_service&
xbox_live_context_impl::presence_service()
{
    return m_presenceService;
}

game_server_platform::game_server_platform_service&
xbox_live_context_impl::game_server_platform_service()
{
    return m_gameServerPlatformService;
}

title_storage::title_storage_service&
xbox_live_context_impl::title_storage_service()
{
    return m_titleStorageService;
}

privacy::privacy_service&
xbox_live_context_impl::privacy_service()
{
    return m_privacyService;
}

system::string_service&
xbox_live_context_impl::string_service()
{
    return m_stringService;
}

contextual_search::contextual_search_service&
xbox_live_context_impl::contextual_search_service()
{
    return m_contextualSearchService;
}

#if UWP_API || XSAPI_U
events::events_service&
xbox_live_context_impl::events_service()
{
    return m_eventsService;
}
#endif

#if TV_API || UNIT_TEST_SERVICES
marketplace::catalog_service&
xbox_live_context_impl::catalog_service()
{
    return m_catalogService;
}

marketplace::inventory_service&
    xbox_live_context_impl::inventory_service()
{
    return m_inventoryService;
}
entertainment_profile::entertainment_profile_list_service&
xbox_live_context_impl::entertainment_profile_list_service()
{
    return m_entertainmentProfileService;
}
#endif

std::shared_ptr<xbox_live_context_settings>
xbox_live_context_impl::settings()
{
    return m_xboxLiveContextSettings;
}

std::shared_ptr<xbox_live_app_config>
xbox_live_context_impl::application_config()
{
    return m_appConfig;
}

NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END<commit_msg>Fixed requesting core windows multiple times (#14)<commit_after>//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************
#include "pch.h"
#include "shared_macros.h"
#include "xsapi/services.h"
#include "user_context.h"
#include "xbox_system_factory.h"
#include "xsapi/system.h"
#include "xbox_live_context_impl.h"
#if !TV_API && !UNIT_TEST_SERVICES && !XSAPI_SERVER
#include "notification_service.h"
#endif
#include "presence_internal.h"
#include "real_time_activity_internal.h"

NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_BEGIN

#if TV_API | XBOX_UWP

xbox_live_context_impl::xbox_live_context_impl(
    _In_ Windows::Xbox::System::User^ user
    ) :
    m_signInContext(0),
    m_signOutContext(0)
{
    m_userContext = std::make_shared<xbox::services::user_context>(user);
}

Windows::Xbox::System::User^
xbox_live_context_impl::user()
{
    return m_userContext->user();
}

#else

xbox_live_context_impl::xbox_live_context_impl(
    _In_ std::shared_ptr<system::xbox_live_user> user
    ) :
    m_signInContext(0),
    m_signOutContext(0)
{
    user->_User_impl()->set_user_pointer(user);
    m_userContext = std::make_shared<xbox::services::user_context>(user);
}

#if XSAPI_CPP
std::shared_ptr<system::xbox_live_user>
xbox_live_context_impl::user()
{
    return m_userContext->user();
}

#else
xbox_live_context_impl::xbox_live_context_impl(
    _In_ Microsoft::Xbox::Services::System::XboxLiveUser^ user
    ) :
    m_signInContext(0),
    m_signOutContext(0)
{
    m_userContext = std::make_shared<xbox::services::user_context>(user);
}

Microsoft::Xbox::Services::System::XboxLiveUser^
xbox_live_context_impl::user()
{
    return m_userContext->user();
}
#endif
#endif

xbox_live_context_impl::~xbox_live_context_impl()
{
    if (m_userContext->user() != nullptr)
    {
#if !TV_API && !UNIT_TEST_SERVICES && !XSAPI_SERVER
#if XSAPI_CPP
        m_userContext->user()->_User_impl()->remove_sign_in_completed_handler(
            m_signInContext
            );

        m_userContext->user()->_User_impl()->remove_sign_out_completed_handler(
            m_signOutContext
            );
#else
        m_userContext->user()->GetUserImpl()->remove_sign_in_completed_handler(
            m_signInContext
            );

        m_userContext->user()->GetUserImpl()->remove_sign_out_completed_handler(
            m_signOutContext
            );
#endif
#endif
    }

    real_time_activity::real_time_activity_service_factory::get_singleton_instance()->remove_user_from_rta_map(m_userContext);
}

void xbox_live_context_impl::init()
{
    xbox_live_result<void> servicesConfigFileReadResult;

    m_appConfig = xbox_live_app_config::get_app_config_singleton();
    m_xboxLiveContextSettings = std::make_shared<xbox::services::xbox_live_context_settings>();
    init_real_time_activity_service_instance();

#if TV_API || UWP_API
    auto dispatcher = xbox_live_context_settings::_s_dispatcher;
    if (dispatcher == nullptr)
    {
        try
        {
            auto mainView = Windows::ApplicationModel::Core::CoreApplication::MainView;
            if (mainView != nullptr)
            {
                auto coreWindow = mainView->CoreWindow;
                if (coreWindow != nullptr)
                {
                    dispatcher = coreWindow->Dispatcher;
                }
            }
        }
        catch (...)
        {
            LOG_ERROR("Protocol activation failed due to inability to acquire a CoreWindow");
        }

        if (dispatcher != nullptr)
        {
            dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
                ref new Windows::UI::Core::DispatchedHandler([]()
            {
                xbox::services::service_call_logging_config::get_singleton_instance()->_Register_for_protocol_activation();
            }));
        }
    }

    xbox::services::service_call_logging_config::get_singleton_instance()->_ReadLocalConfig();
#endif

    std::weak_ptr<xbox_live_context_impl> thisWeakPtr = shared_from_this();

    m_profileService = xbox::services::social::profile_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_reputationService = xbox::services::social::reputation_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_leaderboardService = xbox::services::leaderboard::leaderboard_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_achievementService = xbox::services::achievements::achievement_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, thisWeakPtr);
    m_matchmakingService = xbox::services::matchmaking::matchmaking_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_gameServerPlatformService = xbox::services::game_server_platform::game_server_platform_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_titleStorageService = xbox::services::title_storage::title_storage_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_privacyService = xbox::services::privacy::privacy_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_presenceService = xbox::services::presence::presence_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_userStatisticsService = xbox::services::user_statistics::user_statistics_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_multiplayerService = xbox::services::multiplayer::multiplayer_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_socialService = xbox::services::social::social_service(m_userContext, m_xboxLiveContextSettings, m_appConfig, m_realTimeActivityService);
    m_stringService = xbox::services::system::string_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_contextualSearchService = xbox::services::contextual_search::contextual_search_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);

#if !XSAPI_SERVER

#if UWP_API || XSAPI_U
    m_eventsService = events::events_service(m_userContext, m_appConfig);
#endif

#if TV_API || UNIT_TEST_SERVICES
    // These services are only on XDK
    m_catalogService = marketplace::catalog_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_inventoryService = marketplace::inventory_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    m_entertainmentProfileService = entertainment_profile::entertainment_profile_list_service(m_userContext, m_xboxLiveContextSettings, m_appConfig);
#else

#if !XBOX_UWP

    // Only start the presence writer on UAP
    presence::presence_writer::get_presence_writer_singleton()->start_writer(m_presenceService._Impl());

    auto notificationService = notification::notification_service::get_notification_service_singleton();
    notificationService->subscribe_to_notifications(
        m_userContext,
        m_xboxLiveContextSettings,
        m_appConfig
        );

    if (m_userContext->user() != nullptr)
    {
#if !TV_API && XSAPI_CPP
        m_signInContext = m_userContext->user()->_User_impl()->add_sign_in_completed_handler(
        [thisWeakPtr](const string_t& xboxUserId)
        {
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr && utils::str_icmp(pThis->xbox_live_user_id(), xboxUserId) == 0)
            {
                presence::presence_writer::get_presence_writer_singleton()->start_writer(pThis->m_presenceService._Impl());
            }
        });

        m_signOutContext = m_userContext->user()->_User_impl()->add_sign_out_completed_handler(
            [thisWeakPtr](const system::sign_out_completed_event_args& args)
        {
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr)
            {
                pThis->real_time_activity_service()->_Close_websocket();
                presence::presence_writer::get_presence_writer_singleton()->stop_writer(pThis->xbox_live_user_id());
            }
        });

#elif !TV_API
        m_signInContext = m_userContext->user()->GetUserImpl()->add_sign_in_completed_handler(
            [thisWeakPtr](const string_t& xboxUserId)
        {
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr && utils::str_icmp(pThis->xbox_live_user_id(), xboxUserId) == 0)
            {
                presence::presence_writer::get_presence_writer_singleton()->start_writer(pThis->m_presenceService._Impl());
            }
        });

        m_signOutContext = m_userContext->user()->GetUserImpl()->add_sign_out_completed_handler(
                [thisWeakPtr](const system::sign_out_completed_event_args& args)
        {
            UNREFERENCED_PARAMETER(args);
            std::shared_ptr<xbox_live_context_impl> pThis(thisWeakPtr.lock());
            if (pThis != nullptr)
            {
                pThis->real_time_activity_service()->_Close_websocket();
                presence::presence_writer::get_presence_writer_singleton()->stop_writer(pThis->xbox_live_user_id());
            }
        });
#endif
    }
#endif
#endif
#endif
}

std::shared_ptr<user_context> xbox_live_context_impl::user_context()
{
    return m_userContext;
}

const string_t& xbox_live_context_impl::xbox_live_user_id()
{
    return m_userContext->xbox_user_id();
}

social::profile_service&
xbox_live_context_impl::profile_service()
{
    return m_profileService;
}

social::social_service&
xbox_live_context_impl::social_service()
{
    return m_socialService;
}

social::reputation_service&
xbox_live_context_impl::reputation_service()
{
    return m_reputationService;
}

leaderboard::leaderboard_service&
xbox_live_context_impl::leaderboard_service()
{
    return m_leaderboardService;
}

achievements::achievement_service&
xbox_live_context_impl::achievement_service()
{
    return m_achievementService;
}

multiplayer::multiplayer_service&
xbox_live_context_impl::multiplayer_service()
{
    return m_multiplayerService;
}

matchmaking::matchmaking_service&
xbox_live_context_impl::matchmaking_service()
{
    return m_matchmakingService;
}

user_statistics::user_statistics_service&
xbox_live_context_impl::user_statistics_service()
{
    return m_userStatisticsService;
}

void
xbox_live_context_impl::init_real_time_activity_service_instance()
{
    if (m_userContext->caller_context_type() == caller_context_type::title)
    {
        m_realTimeActivityService = std::shared_ptr<xbox::services::real_time_activity::real_time_activity_service>(new xbox::services::real_time_activity::real_time_activity_service(m_userContext, m_xboxLiveContextSettings, m_appConfig));
    }
    else
    {
        m_realTimeActivityService = real_time_activity::real_time_activity_service_factory::get_singleton_instance()->get_rta_instance(m_userContext, m_xboxLiveContextSettings, m_appConfig);
    }
}

const std::shared_ptr<real_time_activity::real_time_activity_service>&
xbox_live_context_impl::real_time_activity_service()
{
    return m_realTimeActivityService;
}

presence::presence_service&
xbox_live_context_impl::presence_service()
{
    return m_presenceService;
}

game_server_platform::game_server_platform_service&
xbox_live_context_impl::game_server_platform_service()
{
    return m_gameServerPlatformService;
}

title_storage::title_storage_service&
xbox_live_context_impl::title_storage_service()
{
    return m_titleStorageService;
}

privacy::privacy_service&
xbox_live_context_impl::privacy_service()
{
    return m_privacyService;
}

system::string_service&
xbox_live_context_impl::string_service()
{
    return m_stringService;
}

contextual_search::contextual_search_service&
xbox_live_context_impl::contextual_search_service()
{
    return m_contextualSearchService;
}

#if UWP_API || XSAPI_U
events::events_service&
xbox_live_context_impl::events_service()
{
    return m_eventsService;
}
#endif

#if TV_API || UNIT_TEST_SERVICES
marketplace::catalog_service&
xbox_live_context_impl::catalog_service()
{
    return m_catalogService;
}

marketplace::inventory_service&
    xbox_live_context_impl::inventory_service()
{
    return m_inventoryService;
}
entertainment_profile::entertainment_profile_list_service&
xbox_live_context_impl::entertainment_profile_list_service()
{
    return m_entertainmentProfileService;
}
#endif

std::shared_ptr<xbox_live_context_settings>
xbox_live_context_impl::settings()
{
    return m_xboxLiveContextSettings;
}

std::shared_ptr<xbox_live_app_config>
xbox_live_context_impl::application_config()
{
    return m_appConfig;
}

NAMESPACE_MICROSOFT_XBOX_SERVICES_CPP_END<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: YDriver.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:32:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#ifndef CONNECTIVITY_MYSQL_DRIVER_HXX
#define CONNECTIVITY_MYSQL_DRIVER_HXX

#ifndef _COM_SUN_STAR_SDBC_XDRIVER_HPP_
#include <com/sun/star/sdbc/XDriver.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADEFINITIONSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XCREATECATALOG_HPP_
#include <com/sun/star/sdbcx/XCreateCatalog.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _CPPUHELPER_COMPBASE4_HXX_
#include <cppuhelper/compbase4.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include "connectivity/CommonTools.hxx"
#endif

//........................................................................
namespace connectivity
{
//........................................................................

    class OMetaConnection;

    namespace mysql
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ODriverDelegator_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );

        typedef ::cppu::WeakComponentImplHelper4<   ::com::sun::star::sdbc::XDriver
                                        ,::com::sun::star::sdbcx::XDataDefinitionSupplier
                                        , ::com::sun::star::lang::XServiceInfo
                                        ,::com::sun::star::sdbcx::XCreateCatalog
                                        >   ODriverDelegator_BASE;

        typedef ::std::pair< ::com::sun::star::uno::WeakReferenceHelper,OMetaConnection*> TWeakConnectionPair;
        typedef ::std::pair< ::com::sun::star::uno::WeakReferenceHelper,TWeakConnectionPair> TWeakPair;
        typedef ::std::vector< TWeakPair > TWeakPairVector;
        DECLARE_STL_USTRINGACCESS_MAP(::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver >,TJDBCDrivers);

        /** delegates all calls to the orignal driver and extend the existing one with the SDBCX layer.

        */
        class ODriverDelegator : public ::comphelper::OBaseMutex
                                ,public ODriverDelegator_BASE
        {
            TJDBCDrivers                                                        m_aJdbcDrivers; // all jdbc drivers
            TWeakPairVector                                                     m_aConnections; //  vector containing a list
                                                                                //  of all the Connection objects
                                                                                //  for this Driver
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver >                 m_xODBCDriver;
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xFactory;
            ::rtl::OUString     m_sOldDriverClass;
            sal_Bool            m_bUseOdbc;

            /** load the driver we want to delegate.
                The <member>m_xODBCDriver</member> or <member>m_xDBCDriver</member> may be <NULL/> if the driver could not be loaded.
                @param  url
                    The URL.
                @param  info
                    The property info contains which driver we have to delegate.
                @return
                    The driver which was currently selected.
            */
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver > loadDriver( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info );

        public:
            /** creates a new delegator for a mysql driver
            */
            ODriverDelegator(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory);

            // XServiceInfo
            DECLARE_SERVICE_INFO();
            static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
            static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);

            // XDriver
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMajorVersion(  ) throw (::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMinorVersion(  ) throw (::com::sun::star::uno::RuntimeException);

            // XDataDefinitionSupplier
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& connection ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByURL( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

            // XCreateCatalog
            virtual void SAL_CALL createCatalog( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
        protected:
            /// dtor
            virtual ~ODriverDelegator();
            // OComponentHelper
            virtual void SAL_CALL disposing(void);
        };
    }

//........................................................................
}   // namespace connectivity
//........................................................................
#endif // CONNECTIVITY_MYSQL_DRIVER_HXX

<commit_msg>INTEGRATION: CWS warnings01 (1.5.30); FILE MERGED 2005/11/16 12:59:27 fs 1.5.30.1: #i57457# warning free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: YDriver.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 02:04:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#ifndef CONNECTIVITY_MYSQL_DRIVER_HXX
#define CONNECTIVITY_MYSQL_DRIVER_HXX

#ifndef _COM_SUN_STAR_SDBC_XDRIVER_HPP_
#include <com/sun/star/sdbc/XDriver.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADEFINITIONSUPPLIER_HPP_
#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _CPPUHELPER_COMPBASE3_HXX_
#include <cppuhelper/compbase3.hxx>
#endif
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
#endif
#ifndef _COMPHELPER_STLTYPES_HXX_
#include <comphelper/stl_types.hxx>
#endif
#ifndef _COMPHELPER_BROADCASTHELPER_HXX_
#include <comphelper/broadcasthelper.hxx>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include "connectivity/CommonTools.hxx"
#endif

//........................................................................
namespace connectivity
{
//........................................................................

    class OMetaConnection;

    namespace mysql
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ODriverDelegator_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );

        typedef ::cppu::WeakComponentImplHelper3<   ::com::sun::star::sdbc::XDriver
                                                ,   ::com::sun::star::sdbcx::XDataDefinitionSupplier
                                                ,   ::com::sun::star::lang::XServiceInfo
                                                >   ODriverDelegator_BASE;

        typedef ::std::pair< ::com::sun::star::uno::WeakReferenceHelper,OMetaConnection*> TWeakConnectionPair;
        typedef ::std::pair< ::com::sun::star::uno::WeakReferenceHelper,TWeakConnectionPair> TWeakPair;
        typedef ::std::vector< TWeakPair > TWeakPairVector;
        DECLARE_STL_USTRINGACCESS_MAP(::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver >,TJDBCDrivers);

        /** delegates all calls to the orignal driver and extend the existing one with the SDBCX layer.

        */
        class ODriverDelegator : public ::comphelper::OBaseMutex
                                ,public ODriverDelegator_BASE
        {
            TJDBCDrivers                                                        m_aJdbcDrivers; // all jdbc drivers
            TWeakPairVector                                                     m_aConnections; //  vector containing a list
                                                                                //  of all the Connection objects
                                                                                //  for this Driver
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver >                 m_xODBCDriver;
            ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xFactory;
            ::rtl::OUString     m_sOldDriverClass;
            sal_Bool            m_bUseOdbc;

            /** load the driver we want to delegate.
                The <member>m_xODBCDriver</member> or <member>m_xDBCDriver</member> may be <NULL/> if the driver could not be loaded.
                @param  url
                    The URL.
                @param  info
                    The property info contains which driver we have to delegate.
                @return
                    The driver which was currently selected.
            */
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDriver > loadDriver( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info );

        public:
            /** creates a new delegator for a mysql driver
            */
            ODriverDelegator(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory);

            // XServiceInfo
            DECLARE_SERVICE_INFO();
            static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
            static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);

            // XDriver
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMajorVersion(  ) throw (::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMinorVersion(  ) throw (::com::sun::star::uno::RuntimeException);

            // XDataDefinitionSupplier
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& connection ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByURL( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
        protected:
            /// dtor
            virtual ~ODriverDelegator();
            // OComponentHelper
            virtual void SAL_CALL disposing(void);
        };
    }

//........................................................................
}   // namespace connectivity
//........................................................................
#endif // CONNECTIVITY_MYSQL_DRIVER_HXX

<|endoftext|>