<commit_before>#include <msgpack.hpp>
#include <gtest/gtest.h>

TEST(msgpack_tuple, member_get)
{
	msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
	t1.get<0>() = 40;
	t1.get<1>() = false;
	t1.get<2>() = "DEFG";
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}

TEST(msgpack_tuple, non_member_get)
{
	msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
	EXPECT_EQ(42, msgpack::type::get<0>(t1));
	EXPECT_EQ(true, msgpack::type::get<1>(t1));
	EXPECT_EQ("ABC", msgpack::type::get<2>(t1));
	msgpack::type::get<0>(t1) = 40;
	msgpack::type::get<1>(t1) = false;
	msgpack::type::get<2>(t1) = "DEFG";
	EXPECT_EQ(40, msgpack::type::get<0>(t1));
	EXPECT_EQ(false, msgpack::type::get<1>(t1));
	EXPECT_EQ("DEFG", msgpack::type::get<2>(t1));
}

TEST(msgpack_tuple, std_non_member_get)
{
	msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
	EXPECT_EQ(42, std::get<0>(t1));
	EXPECT_EQ(true, std::get<1>(t1));
	EXPECT_EQ("ABC", std::get<2>(t1));
	std::get<0>(t1) = 40;
	std::get<1>(t1) = false;
	std::get<2>(t1) = "DEFG";
	EXPECT_EQ(40, std::get<0>(t1));
	EXPECT_EQ(false, std::get<1>(t1));
	EXPECT_EQ("DEFG", std::get<2>(t1));
}

TEST(msgpack_tuple, make_tuple)
{
	msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::make_tuple(42, true, "ABC");
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
	t1.get<0>() = 40;
	t1.get<1>() = false;
	t1.get<2>() = "DEFG";
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());

	msgpack::type::tuple<int, bool, std::string> t2 =
		msgpack::type::make_tuple(std::make_tuple(42, true, "ABC"));
	EXPECT_EQ(42, t2.get<0>());
	EXPECT_EQ(true, t2.get<1>());
	EXPECT_EQ("ABC", t2.get<2>());

}

TEST(msgpack_tuple, tie)
{
	int i(42);
	bool b(true);
	std::string s("ABC");
	msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::tie(i, b, s);
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
	t1.get<0>() = 40;
	t1.get<1>() = false;
	t1.get<2>() = "DEFG";
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}

TEST(msgpack_tuple, tuple_cat)
{
	msgpack::type::tuple<int> t1 = msgpack::type::make_tuple(42);
	msgpack::type::tuple<bool, std::string> t2 = msgpack::type::make_tuple(true, "ABC");
	msgpack::type::tuple<int, bool, std::string> t3 = msgpack::type::tuple_cat(t1, std::move(t2));
	EXPECT_EQ(42, t3.get<0>());
	EXPECT_EQ(true, t3.get<1>());
	EXPECT_EQ("ABC", t3.get<2>());
}

TEST(msgpack_tuple, swap)
{
	msgpack::type::tuple<int, bool, std::string>  t1 = msgpack::type::make_tuple(42, true, "ABC");
	msgpack::type::tuple<int, bool, std::string>  t2 = msgpack::type::make_tuple(40, false, "DEFG");
	msgpack::type::swap(t1, t2);
	EXPECT_EQ(42, t2.get<0>());
	EXPECT_EQ(true, t2.get<1>());
	EXPECT_EQ("ABC", t2.get<2>());
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}
<commit_msg>Tests for msgpack::type::tuple C++11 expansion moved to __cplusplus >= 201103.<commit_after>#include <msgpack.hpp>
#include <gtest/gtest.h>

TEST(msgpack_tuple, member_get)
{
	msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
	t1.get<0>() = 40;
	t1.get<1>() = false;
	t1.get<2>() = "DEFG";
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}

TEST(msgpack_tuple, non_member_get)
{
	msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
	EXPECT_EQ(42, msgpack::type::get<0>(t1));
	EXPECT_EQ(true, msgpack::type::get<1>(t1));
	EXPECT_EQ("ABC", msgpack::type::get<2>(t1));
	msgpack::type::get<0>(t1) = 40;
	msgpack::type::get<1>(t1) = false;
	msgpack::type::get<2>(t1) = "DEFG";
	EXPECT_EQ(40, msgpack::type::get<0>(t1));
	EXPECT_EQ(false, msgpack::type::get<1>(t1));
	EXPECT_EQ("DEFG", msgpack::type::get<2>(t1));
}

#if __cplusplus >= 201103
TEST(msgpack_tuple, std_non_member_get)
{
	msgpack::type::tuple<int, bool, std::string> t1(42, true, "ABC");
	EXPECT_EQ(42, std::get<0>(t1));
	EXPECT_EQ(true, std::get<1>(t1));
	EXPECT_EQ("ABC", std::get<2>(t1));
	std::get<0>(t1) = 40;
	std::get<1>(t1) = false;
	std::get<2>(t1) = "DEFG";
	EXPECT_EQ(40, std::get<0>(t1));
	EXPECT_EQ(false, std::get<1>(t1));
	EXPECT_EQ("DEFG", std::get<2>(t1));
}

TEST(msgpack_tuple, make_tuple)
{
	msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::make_tuple(42, true, "ABC");
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
	t1.get<0>() = 40;
	t1.get<1>() = false;
	t1.get<2>() = "DEFG";
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}

TEST(msgpack_tuple, std_make_tuple)
{
	msgpack::type::tuple<int, bool, std::string> t1 =
		msgpack::type::make_tuple(std::make_tuple(42, true, "ABC"));
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
}

TEST(msgpack_tuple, tie)
{
	int i(42);
	bool b(true);
	std::string s("ABC");
	msgpack::type::tuple<int, bool, std::string> t1 = msgpack::type::tie(i, b, s);
	EXPECT_EQ(42, t1.get<0>());
	EXPECT_EQ(true, t1.get<1>());
	EXPECT_EQ("ABC", t1.get<2>());
	t1.get<0>() = 40;
	t1.get<1>() = false;
	t1.get<2>() = "DEFG";
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}

TEST(msgpack_tuple, tuple_cat)
{
	msgpack::type::tuple<int> t1 = msgpack::type::make_tuple(42);
	msgpack::type::tuple<bool, std::string> t2 = msgpack::type::make_tuple(true, "ABC");
	msgpack::type::tuple<int, bool, std::string> t3 = msgpack::type::tuple_cat(t1, std::move(t2));
	EXPECT_EQ(42, t3.get<0>());
	EXPECT_EQ(true, t3.get<1>());
	EXPECT_EQ("ABC", t3.get<2>());
}

TEST(msgpack_tuple, swap)
{
	msgpack::type::tuple<int, bool, std::string>  t1 = msgpack::type::make_tuple(42, true, "ABC");
	msgpack::type::tuple<int, bool, std::string>  t2 = msgpack::type::make_tuple(40, false, "DEFG");
	msgpack::type::swap(t1, t2);
	EXPECT_EQ(42, t2.get<0>());
	EXPECT_EQ(true, t2.get<1>());
	EXPECT_EQ("ABC", t2.get<2>());
	EXPECT_EQ(40, t1.get<0>());
	EXPECT_EQ(false, t1.get<1>());
	EXPECT_EQ("DEFG", t1.get<2>());
}
#endif
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
  typedef typename MatrixType::Scalar Scalar;
  if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
    VERIFY(sizeof(MatrixType)==static_cast<int>(sizeof(Scalar))*MatrixType::SizeAtCompileTime);
  else
    VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}

void test_sizeof()
{
  CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );
  CALL_SUBTEST(verifySizeOf(Matrix4d()) );
  CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );
  CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );
  CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );
  CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );
  CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );
  CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );

  VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));
  VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));
}
<commit_msg>fix icc warning #68<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

#include "main.h"

template<typename MatrixType> void verifySizeOf(const MatrixType&)
{
  typedef typename MatrixType::Scalar Scalar;
  if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)
    VERIFY(sizeof(MatrixType)==sizeof(Scalar)*size_t(MatrixType::SizeAtCompileTime));
  else
    VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));
}

void test_sizeof()
{
  CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );
  CALL_SUBTEST(verifySizeOf(Matrix4d()) );
  CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );
  CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );
  CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );
  CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );
  CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );
  CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );

  VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));
  VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));
}
<|endoftext|>


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

#include "radfiledata.h"
#include "gtest/gtest.h"
#include <iostream>
#include "materialprimitives.h"
#include "geometryprimitives.h"
#include "functions.h"

TEST(RadFileTests, ParseRadFile)
{
  stadic::RadFileData radData;
  ASSERT_TRUE(radData.addRad("Simple.rad"));
  ASSERT_EQ(36, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(0, radData.materials().size());
  ASSERT_TRUE(radData.addRad("material.rad"));
  //Testing to ensure all of the primitives are read in
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(6, radData.materials().size());

  //Testing First Polygon for contents
  EXPECT_EQ("l_floor", radData.geometry().at(0)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Polygon, radData.geometry().at(0)->type());
  EXPECT_EQ("l_floor.0.1", radData.geometry().at(0)->name());
  EXPECT_EQ(0, radData.geometry().at(0)->arg1().size());
  EXPECT_EQ(0, radData.geometry().at(0)->arg2().size());
  ASSERT_EQ(12, radData.geometry().at(0)->arg3().size());
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(0)->arg3().at(0)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(0)->arg3().at(3)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(0)->arg3().at(6)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(0)->arg3().at(10)));

  //Testing Last Polygon for contents
  EXPECT_EQ("l_ceiling", radData.geometry().at(radData.geometry().size()-1)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Polygon, radData.geometry().at(radData.geometry().size()-1)->type());
  EXPECT_EQ("l_ceiling.39.1", radData.geometry().at(radData.geometry().size()-1)->name());
  EXPECT_EQ(0, radData.geometry().at(radData.geometry().size()-1)->arg1().size());
  EXPECT_EQ(0, radData.geometry().at(radData.geometry().size()-1)->arg2().size());
  ASSERT_EQ(12, radData.geometry().at(radData.geometry().size()-1)->arg3().size());
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(0)));
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(3)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(6)));
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(10)));

  //Testing first material for contents
  EXPECT_EQ("void", radData.materials().at(0)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Plastic, radData.materials().at(0)->type());
  EXPECT_EQ("l_wall", radData.materials().at(0)->name());
  EXPECT_EQ(0, radData.materials().at(0)->arg1().size());
  EXPECT_EQ(0, radData.materials().at(0)->arg2().size());
  ASSERT_EQ(5, radData.materials().at(0)->arg3().size());
  EXPECT_EQ(.5, stadic::toDouble(radData.materials().at(0)->arg3().at(0)));
  EXPECT_EQ(.5, stadic::toDouble(radData.materials().at(0)->arg3().at(1)));
  EXPECT_EQ(.5, stadic::toDouble(radData.materials().at(0)->arg3().at(2)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(0)->arg3().at(3)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(0)->arg3().at(4)));

  //Testing second material for contents
  EXPECT_EQ("void", radData.materials().at(1)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Glass, radData.materials().at(1)->type());
  EXPECT_EQ("l_window", radData.materials().at(1)->name());
  EXPECT_EQ(0, radData.materials().at(1)->arg1().size());
  EXPECT_EQ(0, radData.materials().at(1)->arg2().size());
  ASSERT_EQ(3, radData.materials().at(1)->arg3().size());
  EXPECT_EQ(.65, stadic::toDouble(radData.materials().at(1)->arg3().at(0)));
  EXPECT_EQ(.65, stadic::toDouble(radData.materials().at(1)->arg3().at(1)));
  EXPECT_EQ(.65, stadic::toDouble(radData.materials().at(1)->arg3().at(2)));

  //Testing last material for contents
  EXPECT_EQ("void", radData.materials().at(radData.materials().size()-1)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Plastic, radData.materials().at(radData.materials().size()-1)->type());
  EXPECT_EQ("l_ceiling", radData.materials().at(radData.materials().size()-1)->name());
  EXPECT_EQ(0, radData.materials().at(radData.materials().size()-1)->arg1().size());
  EXPECT_EQ(0, radData.materials().at(radData.materials().size()-1)->arg2().size());
  ASSERT_EQ(5, radData.materials().at(radData.materials().size()-1)->arg3().size());
  EXPECT_EQ(.8, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(0)));
  EXPECT_EQ(.8, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(1)));
  EXPECT_EQ(.8, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(2)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(3)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(4)));

  //Test getting primitives by type
  shared_vector<stadic::PlasticMaterial> plastic = radData.getPrimitives<stadic::PlasticMaterial>();
  ASSERT_EQ(5,plastic.size());

  //Testing second plastic for contents
  EXPECT_EQ("l_extwall",plastic[1]->name());
  EXPECT_EQ(.15,plastic[1]->red());
  EXPECT_EQ(.15,plastic[1]->green());
  EXPECT_EQ(.15,plastic[1]->blue());
  EXPECT_EQ(0,plastic[1]->specularity());
  EXPECT_EQ(0,plastic[1]->roughness());
}

bool isGlass(stadic::RadPrimitive* primitive)
{
    return primitive->type() == stadic::RadPrimitive::Glass;
}
bool nameStartsWith(stadic::RadPrimitive* primitive, const std::string &name)
{
    if (primitive->name().compare(0,name.length(),name)==0){
        return true;
    }
    return false;
  //return primitive->name().startsWith(name);
}

TEST(RadFileTests, SplitRadFile)
{
    // All of the split stuff needs to be reworked, so this test will fail until that happens
    /*
  stadic::RadFileData radData;
  ASSERT_TRUE(radData.addRad("Simple.rad"));
  ASSERT_EQ(36, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(0, radData.materials().size());
  ASSERT_TRUE(radData.addRad("material.rad"));
  //Testing to ensure all of the primitives are read in
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(6, radData.materials().size());
  // Split based on whether the type is glass or not
  QPair<stadic::RadFileData*, stadic::RadFileData*> splitGlass = radData.split(isGlass);
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_NE(nullptr, splitGlass.first);
  ASSERT_NE(nullptr, splitGlass.second);
  ASSERT_EQ(1, splitGlass.first->primitives().size());
  ASSERT_EQ(41, splitGlass.second->primitives().size());
  // Split based on what the name starts with
  QPair<stadic::RadFileData*, stadic::RadFileData*> splitName = radData.split(nameStartsWith,QString("l_wa"));
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_NE(nullptr, splitName.first);
  ASSERT_NE(nullptr, splitName.second);
  ASSERT_EQ(17, splitName.first->primitives().size());
  ASSERT_EQ(25, splitName.second->primitives().size());
  // Split based on layer names
  std::vector<QString> names;
  names.push_back("l_ceiling");
  names.push_back("l_floor");
  QPair<stadic::RadFileData*, stadic::RadFileData*> splitLayers = radData.split(names);
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_NE(nullptr, splitLayers.first);
  ASSERT_NE(nullptr, splitLayers.second);
  ASSERT_EQ(4, splitLayers.first->primitives().size());
  ASSERT_EQ(38, splitLayers.second->primitives().size());
  */
    ASSERT_TRUE(false);
}

TEST(RadFileTests, ParseComplicatedRadFile)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("complicated.rad"));
    EXPECT_EQ(112, radData.primitives().size());
    EXPECT_EQ(8, radData.materials().size());
    EXPECT_EQ(104, radData.geometry().size());
}

TEST(RadFileTests, WriteSimpleRadFile)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("Simple.rad"));
    ASSERT_TRUE(radData.writeRadFile("simpletest.rad"));
    stadic::RadFileData reread;
    ASSERT_TRUE(reread.addRad("simpletest.rad"));
    EXPECT_EQ(radData.primitives().size(), reread.primitives().size());
}

TEST(RadFileTests, PlasticTest)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("plasticmaterial.rad"));
    ASSERT_EQ(3, radData.primitives().size());
    auto plastic = std::dynamic_pointer_cast<stadic::PlasticMaterial>(radData.primitives()[0]);
    ASSERT_TRUE(plastic);
    EXPECT_EQ(0.5, plastic->red());
    EXPECT_EQ(0.5, plastic->green());
    EXPECT_EQ(0.5, plastic->blue());
    EXPECT_EQ(0, plastic->roughness());
    EXPECT_EQ(0, plastic->specularity());
    plastic = std::dynamic_pointer_cast<stadic::PlasticMaterial>(radData.primitives()[1]);
    ASSERT_TRUE(plastic);
    EXPECT_EQ(0, plastic->red());
    EXPECT_EQ(0, plastic->green());
    EXPECT_EQ(0, plastic->blue());
    EXPECT_EQ(0, plastic->roughness());
    EXPECT_EQ(0, plastic->specularity());
    plastic = std::dynamic_pointer_cast<stadic::PlasticMaterial>(radData.primitives()[2]);
    ASSERT_TRUE(plastic);
    EXPECT_EQ(0.25, plastic->red());
    EXPECT_EQ(0.25, plastic->green());
    EXPECT_EQ(0.25, plastic->blue());
    EXPECT_EQ(0, plastic->roughness());
    EXPECT_EQ(0, plastic->specularity());

}

TEST(RadFileTests, PolygonTest)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("polygongeometry.rad"));
    ASSERT_EQ(3, radData.primitives().size());
    auto primitive = std::dynamic_pointer_cast<stadic::PolygonGeometry>(radData.primitives()[0]);
    ASSERT_TRUE(primitive);
    ASSERT_EQ(12, primitive->arg3().size());
    primitive = std::dynamic_pointer_cast<stadic::PolygonGeometry>(radData.primitives()[1]);
    ASSERT_TRUE(primitive);
    ASSERT_EQ(0, primitive->arg3().size());
    primitive = std::dynamic_pointer_cast<stadic::PolygonGeometry>(radData.primitives()[2]);
    ASSERT_TRUE(primitive);
    ASSERT_EQ(12, primitive->arg3().size());

}<commit_msg>Include name and modifier in tests<commit_after>/****************************************************************
 * Copyright (c) 2014, The Pennsylvania State University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms,
 * with or without modification, are permitted for
 * personal and commercial purposes provided that the
 * following conditions are met:
 *
 * 1. Redistribution of source code must retain the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer.
 *
 * 2. Redistribution in binary form must reproduce the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer.
 *
 * 3. Neither the name of The Pennsylvania State University
 *    nor the names of its contributors may be used to
 *    endorse or promote products derived from this software
 *    without the specific prior written permission of The
 *    Pennsylvania State University.
 *
 * THIS SOFTWARE IS PROVIDED BY THE PENNSYLVANIA STATE UNIVERSITY
 * "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF
 * INTELLECTUAL PROPERTY ARE EXPRESSLY DISCLAIMED. IN NO EVENT
 * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 ****************************************************************/

#include "radfiledata.h"
#include "gtest/gtest.h"
#include <iostream>
#include "materialprimitives.h"
#include "geometryprimitives.h"
#include "functions.h"

TEST(RadFileTests, ParseRadFile)
{
  stadic::RadFileData radData;
  ASSERT_TRUE(radData.addRad("Simple.rad"));
  ASSERT_EQ(36, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(0, radData.materials().size());
  ASSERT_TRUE(radData.addRad("material.rad"));
  //Testing to ensure all of the primitives are read in
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(6, radData.materials().size());

  //Testing First Polygon for contents
  EXPECT_EQ("l_floor", radData.geometry().at(0)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Polygon, radData.geometry().at(0)->type());
  EXPECT_EQ("l_floor.0.1", radData.geometry().at(0)->name());
  EXPECT_EQ(0, radData.geometry().at(0)->arg1().size());
  EXPECT_EQ(0, radData.geometry().at(0)->arg2().size());
  ASSERT_EQ(12, radData.geometry().at(0)->arg3().size());
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(0)->arg3().at(0)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(0)->arg3().at(3)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(0)->arg3().at(6)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(0)->arg3().at(10)));

  //Testing Last Polygon for contents
  EXPECT_EQ("l_ceiling", radData.geometry().at(radData.geometry().size()-1)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Polygon, radData.geometry().at(radData.geometry().size()-1)->type());
  EXPECT_EQ("l_ceiling.39.1", radData.geometry().at(radData.geometry().size()-1)->name());
  EXPECT_EQ(0, radData.geometry().at(radData.geometry().size()-1)->arg1().size());
  EXPECT_EQ(0, radData.geometry().at(radData.geometry().size()-1)->arg2().size());
  ASSERT_EQ(12, radData.geometry().at(radData.geometry().size()-1)->arg3().size());
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(0)));
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(3)));
  EXPECT_EQ(240, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(6)));
  EXPECT_EQ(0, stadic::toDouble(radData.geometry().at(radData.geometry().size()-1)->arg3().at(10)));

  //Testing first material for contents
  EXPECT_EQ("void", radData.materials().at(0)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Plastic, radData.materials().at(0)->type());
  EXPECT_EQ("l_wall", radData.materials().at(0)->name());
  EXPECT_EQ(0, radData.materials().at(0)->arg1().size());
  EXPECT_EQ(0, radData.materials().at(0)->arg2().size());
  ASSERT_EQ(5, radData.materials().at(0)->arg3().size());
  EXPECT_EQ(.5, stadic::toDouble(radData.materials().at(0)->arg3().at(0)));
  EXPECT_EQ(.5, stadic::toDouble(radData.materials().at(0)->arg3().at(1)));
  EXPECT_EQ(.5, stadic::toDouble(radData.materials().at(0)->arg3().at(2)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(0)->arg3().at(3)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(0)->arg3().at(4)));

  //Testing second material for contents
  EXPECT_EQ("void", radData.materials().at(1)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Glass, radData.materials().at(1)->type());
  EXPECT_EQ("l_window", radData.materials().at(1)->name());
  EXPECT_EQ(0, radData.materials().at(1)->arg1().size());
  EXPECT_EQ(0, radData.materials().at(1)->arg2().size());
  ASSERT_EQ(3, radData.materials().at(1)->arg3().size());
  EXPECT_EQ(.65, stadic::toDouble(radData.materials().at(1)->arg3().at(0)));
  EXPECT_EQ(.65, stadic::toDouble(radData.materials().at(1)->arg3().at(1)));
  EXPECT_EQ(.65, stadic::toDouble(radData.materials().at(1)->arg3().at(2)));

  //Testing last material for contents
  EXPECT_EQ("void", radData.materials().at(radData.materials().size()-1)->modifier());
  EXPECT_EQ(stadic::RadPrimitive::Plastic, radData.materials().at(radData.materials().size()-1)->type());
  EXPECT_EQ("l_ceiling", radData.materials().at(radData.materials().size()-1)->name());
  EXPECT_EQ(0, radData.materials().at(radData.materials().size()-1)->arg1().size());
  EXPECT_EQ(0, radData.materials().at(radData.materials().size()-1)->arg2().size());
  ASSERT_EQ(5, radData.materials().at(radData.materials().size()-1)->arg3().size());
  EXPECT_EQ(.8, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(0)));
  EXPECT_EQ(.8, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(1)));
  EXPECT_EQ(.8, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(2)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(3)));
  EXPECT_EQ(0, stadic::toDouble(radData.materials().at(radData.materials().size()-1)->arg3().at(4)));

  //Test getting primitives by type
  shared_vector<stadic::PlasticMaterial> plastic = radData.getPrimitives<stadic::PlasticMaterial>();
  ASSERT_EQ(5,plastic.size());

  //Testing second plastic for contents
  EXPECT_EQ("l_extwall",plastic[1]->name());
  EXPECT_EQ(.15,plastic[1]->red());
  EXPECT_EQ(.15,plastic[1]->green());
  EXPECT_EQ(.15,plastic[1]->blue());
  EXPECT_EQ(0,plastic[1]->specularity());
  EXPECT_EQ(0,plastic[1]->roughness());
}

bool isGlass(stadic::RadPrimitive* primitive)
{
    return primitive->type() == stadic::RadPrimitive::Glass;
}
bool nameStartsWith(stadic::RadPrimitive* primitive, const std::string &name)
{
    if (primitive->name().compare(0,name.length(),name)==0){
        return true;
    }
    return false;
  //return primitive->name().startsWith(name);
}

TEST(RadFileTests, SplitRadFile)
{
    // All of the split stuff needs to be reworked, so this test will fail until that happens
    /*
  stadic::RadFileData radData;
  ASSERT_TRUE(radData.addRad("Simple.rad"));
  ASSERT_EQ(36, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(0, radData.materials().size());
  ASSERT_TRUE(radData.addRad("material.rad"));
  //Testing to ensure all of the primitives are read in
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_EQ(36, radData.geometry().size());
  ASSERT_EQ(6, radData.materials().size());
  // Split based on whether the type is glass or not
  QPair<stadic::RadFileData*, stadic::RadFileData*> splitGlass = radData.split(isGlass);
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_NE(nullptr, splitGlass.first);
  ASSERT_NE(nullptr, splitGlass.second);
  ASSERT_EQ(1, splitGlass.first->primitives().size());
  ASSERT_EQ(41, splitGlass.second->primitives().size());
  // Split based on what the name starts with
  QPair<stadic::RadFileData*, stadic::RadFileData*> splitName = radData.split(nameStartsWith,QString("l_wa"));
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_NE(nullptr, splitName.first);
  ASSERT_NE(nullptr, splitName.second);
  ASSERT_EQ(17, splitName.first->primitives().size());
  ASSERT_EQ(25, splitName.second->primitives().size());
  // Split based on layer names
  std::vector<QString> names;
  names.push_back("l_ceiling");
  names.push_back("l_floor");
  QPair<stadic::RadFileData*, stadic::RadFileData*> splitLayers = radData.split(names);
  ASSERT_EQ(42, radData.primitives().size());
  ASSERT_NE(nullptr, splitLayers.first);
  ASSERT_NE(nullptr, splitLayers.second);
  ASSERT_EQ(4, splitLayers.first->primitives().size());
  ASSERT_EQ(38, splitLayers.second->primitives().size());
  */
    ASSERT_TRUE(false);
}

TEST(RadFileTests, ParseComplicatedRadFile)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("complicated.rad"));
    EXPECT_EQ(112, radData.primitives().size());
    EXPECT_EQ(8, radData.materials().size());
    EXPECT_EQ(104, radData.geometry().size());
}

TEST(RadFileTests, WriteSimpleRadFile)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("Simple.rad"));
    ASSERT_TRUE(radData.writeRadFile("simpletest.rad"));
    stadic::RadFileData reread;
    ASSERT_TRUE(reread.addRad("simpletest.rad"));
    EXPECT_EQ(radData.primitives().size(), reread.primitives().size());
}

TEST(RadFileTests, PlasticTest)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("plasticmaterial.rad"));
    ASSERT_EQ(3, radData.primitives().size());
    auto primitive = std::dynamic_pointer_cast<stadic::PlasticMaterial>(radData.primitives()[0]);
    ASSERT_TRUE(primitive);
    EXPECT_EQ("void", primitive->modifier());
    EXPECT_EQ("l_wall", primitive->name());
    EXPECT_EQ(0.5, primitive->red());
    EXPECT_EQ(0.5, primitive->green());
    EXPECT_EQ(0.5, primitive->blue());
    EXPECT_EQ(0, primitive->roughness());
    EXPECT_EQ(0, primitive->specularity());
    primitive = std::dynamic_pointer_cast<stadic::PlasticMaterial>(radData.primitives()[1]);
    ASSERT_TRUE(primitive);
    EXPECT_EQ("void", primitive->modifier());
    EXPECT_EQ("l_extwall", primitive->name());
    EXPECT_EQ(0, primitive->red());
    EXPECT_EQ(0, primitive->green());
    EXPECT_EQ(0, primitive->blue());
    EXPECT_EQ(0, primitive->roughness());
    EXPECT_EQ(0, primitive->specularity());
    primitive = std::dynamic_pointer_cast<stadic::PlasticMaterial>(radData.primitives()[2]);
    ASSERT_TRUE(primitive);
    EXPECT_EQ("void", primitive->modifier());
    EXPECT_EQ("l_floor", primitive->name());
    EXPECT_EQ(0.25, primitive->red());
    EXPECT_EQ(0.25, primitive->green());
    EXPECT_EQ(0.25, primitive->blue());
    EXPECT_EQ(0, primitive->roughness());
    EXPECT_EQ(0, primitive->specularity());

}

TEST(RadFileTests, PolygonTest)
{
    stadic::RadFileData radData;
    ASSERT_TRUE(radData.addRad("polygongeometry.rad"));
    ASSERT_EQ(3, radData.primitives().size());
    auto primitive = std::dynamic_pointer_cast<stadic::PolygonGeometry>(radData.primitives()[0]);
    ASSERT_TRUE(primitive);
    ASSERT_EQ(12, primitive->arg3().size());
    EXPECT_EQ("l_floor", primitive->modifier());
    EXPECT_EQ("l_floor.0.1", primitive->name());
    primitive = std::dynamic_pointer_cast<stadic::PolygonGeometry>(radData.primitives()[1]);
    ASSERT_TRUE(primitive);
    ASSERT_EQ(0, primitive->arg3().size());
    EXPECT_EQ("l_wall", primitive->modifier());
    EXPECT_EQ("l_wall.1.1", primitive->name());
    primitive = std::dynamic_pointer_cast<stadic::PolygonGeometry>(radData.primitives()[2]);
    ASSERT_TRUE(primitive);
    ASSERT_EQ(12, primitive->arg3().size());
    EXPECT_EQ("l_wall", primitive->modifier());
    EXPECT_EQ("l_wall.2.1", primitive->name());

}<|endoftext|>


<commit_before>/*
 Copyright 2015 Aleix Pol Gonzalez <aleixpol@blue-systems.com>

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

 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, see <http://www.gnu.org/licenses/>.
*/

#include <QApplication>
#include <QFileInfo>
#include <QMetaMethod>
#include <KPluginMetaData>
#include <QCommandLineParser>
#include <QJsonDocument>
#include <QPointer>
#include <QLocalSocket>

#include "helper.h"
#include <purpose/configuration.h>
#include <purpose/job.h>

static QString pluginType;
static KPluginMetaData md;

class Communication : public QObject
{
Q_OBJECT
public:
    Communication(const QString &serverName)
    {
        int pcIdx = metaObject()->indexOfSlot("propertyChanged()");
        Q_ASSERT(pcIdx>=0);
        const QMetaMethod propertyChangedMethod = metaObject()->method(pcIdx);

        m_socket.setServerName(serverName);
        m_socket.connectToServer(QIODevice::ReadWrite);
        connect(&m_socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(error()));

        bool b = m_socket.waitForConnected();
        Q_ASSERT(b);

        b = m_socket.waitForReadyRead();
        Q_ASSERT(b);

        Q_ASSERT(m_socket.canReadLine());
        QByteArray byteLine = m_socket.readLine();
        byteLine.chop(1); // Drop \n
        const qint64 bytes = byteLine.toLongLong();
        // QByteArray and QJsonDocument::from* can only handle int size.
        // If the payload is bigger we are screwed.
        Q_ASSERT(bytes <= std::numeric_limits<int>::max());

        QByteArray dataArray;
        dataArray.resize(bytes);
        int pos = 0;
        bool couldRead = false;
        while ((pos < bytes) && (couldRead = (m_socket.bytesAvailable() || m_socket.waitForReadyRead()))) {
            pos += m_socket.read(dataArray.data() + pos, qMin(m_socket.bytesAvailable(), bytes-pos));
        }
        Q_ASSERT(couldRead); // false if we hit a timeout before read-end.
        Q_ASSERT(pos == bytes);

        Purpose::Configuration config(QJsonDocument::fromJson(dataArray).object(), pluginType, md);
        config.setUseSeparateProcess(false);

        Q_ASSERT(config.isReady());

        m_job = config.createJob();
        m_job->start();

        const QMetaObject* m = m_job->metaObject();
        for(int i = 0, c = m->propertyCount(); i<c; ++i) {
            QMetaProperty prop = m->property(i);
                connect(m_job, prop.notifySignal(), this, propertyChangedMethod);
            if (prop.hasNotifySignal() && prop.isReadable()) {
            }
        }
    }

private Q_SLOTS:
    void error() {
        qWarning() << "socket error:" << m_socket.error();
    }

    void propertyChanged() {
        const int idx = senderSignalIndex();

        const QMetaObject* m = m_job->metaObject();
        QJsonObject toSend;
        for(int i = 0, c = m->propertyCount(); i<c; ++i) {
            QMetaProperty prop = m->property(i);
            if (prop.notifySignalIndex() == idx) {
                toSend[QString::fromLatin1(prop.name())] = fromVariant(prop.read(m_job));
            }
        }
        send(toSend);
    }

    static QJsonValue fromVariant(const QVariant &var) {
        if (var.canConvert<QJsonObject>()) {
            return var.toJsonObject();
        } else {
            return QJsonValue::fromVariant(var);
        }
    }

private:
    void send(const QJsonObject &object) {
        const QByteArray data = QJsonDocument(object).toJson(QJsonDocument::Compact) + '\n';
//         qDebug() << "sending..." << data;
        m_socket.write(data);
    }

    Purpose::Job* m_job = nullptr;
    QLocalSocket m_socket;
};

int main(int argc, char** argv)
{
#warning make QGuiApplication, consider QCoreApplication?
    QApplication app(argc, argv);

    QString serverName;

    {
        QCommandLineParser parser;
        parser.addOption(QCommandLineOption(QStringLiteral("server"), QStringLiteral("Named socket to connect to"), QStringLiteral("name")));
        parser.addOption(QCommandLineOption(QStringLiteral("pluginPath"), QStringLiteral("Chosen plugin"), QStringLiteral("path")));
        parser.addOption(QCommandLineOption(QStringLiteral("pluginType"), QStringLiteral("Plugin type name "), QStringLiteral("path")));
        parser.addHelpOption();

        parser.process(app);

        serverName = parser.value(QStringLiteral("server"));
        pluginType = parser.value(QStringLiteral("pluginType"));

        const QString path = parser.value(QStringLiteral("pluginPath"));
        if (path.endsWith(QLatin1String("/metadata.json"))) {
            QFileInfo fi(path);
            md = Purpose::createMetaData(path);
        } else {
            md = KPluginMetaData(path);
            Q_ASSERT(md.isValid());
        }
    }

    Communication c(serverName);

    return app.exec();
}

#include "purposeprocess_main.moc"
<commit_msg>Just connect to a signal once<commit_after>/*
 Copyright 2015 Aleix Pol Gonzalez <aleixpol@blue-systems.com>

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

 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, see <http://www.gnu.org/licenses/>.
*/

#include <QApplication>
#include <QFileInfo>
#include <QMetaMethod>
#include <KPluginMetaData>
#include <QCommandLineParser>
#include <QJsonDocument>
#include <QPointer>
#include <QLocalSocket>

#include "helper.h"
#include <purpose/configuration.h>
#include <purpose/job.h>

static QString pluginType;
static KPluginMetaData md;

class Communication : public QObject
{
Q_OBJECT
public:
    Communication(const QString &serverName)
    {
        int pcIdx = metaObject()->indexOfSlot("propertyChanged()");
        Q_ASSERT(pcIdx>=0);
        const QMetaMethod propertyChangedMethod = metaObject()->method(pcIdx);

        m_socket.setServerName(serverName);
        m_socket.connectToServer(QIODevice::ReadWrite);
        connect(&m_socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(error()));

        bool b = m_socket.waitForConnected();
        Q_ASSERT(b);

        b = m_socket.waitForReadyRead();
        Q_ASSERT(b);

        Q_ASSERT(m_socket.canReadLine());
        QByteArray byteLine = m_socket.readLine();
        byteLine.chop(1); // Drop \n
        const qint64 bytes = byteLine.toLongLong();
        // QByteArray and QJsonDocument::from* can only handle int size.
        // If the payload is bigger we are screwed.
        Q_ASSERT(bytes <= std::numeric_limits<int>::max());

        QByteArray dataArray;
        dataArray.resize(bytes);
        int pos = 0;
        bool couldRead = false;
        while ((pos < bytes) && (couldRead = (m_socket.bytesAvailable() || m_socket.waitForReadyRead()))) {
            pos += m_socket.read(dataArray.data() + pos, qMin(m_socket.bytesAvailable(), bytes-pos));
        }
        Q_ASSERT(couldRead); // false if we hit a timeout before read-end.
        Q_ASSERT(pos == bytes);

        Purpose::Configuration config(QJsonDocument::fromJson(dataArray).object(), pluginType, md);
        config.setUseSeparateProcess(false);

        Q_ASSERT(config.isReady());

        m_job = config.createJob();
        m_job->start();

        const QMetaObject* m = m_job->metaObject();
        for(int i = 0, c = m->propertyCount(); i<c; ++i) {
            QMetaProperty prop = m->property(i);
            if (prop.hasNotifySignal() && prop.isReadable()) {
                connect(m_job, prop.notifySignal(), this, propertyChangedMethod, Qt::UniqueConnection);
            }
        }
    }

private Q_SLOTS:
    void error() {
        qWarning() << "socket error:" << m_socket.error();
    }

    void propertyChanged() {
        const int idx = senderSignalIndex();

        const QMetaObject* m = m_job->metaObject();
        QJsonObject toSend;
        for(int i = 0, c = m->propertyCount(); i<c; ++i) {
            QMetaProperty prop = m->property(i);
            if (prop.notifySignalIndex() == idx) {
                toSend[QString::fromLatin1(prop.name())] = fromVariant(prop.read(m_job));
            }
        }
        send(toSend);
    }

    static QJsonValue fromVariant(const QVariant &var) {
        if (var.canConvert<QJsonObject>()) {
            return var.toJsonObject();
        } else {
            return QJsonValue::fromVariant(var);
        }
    }

private:
    void send(const QJsonObject &object) {
        const QByteArray data = QJsonDocument(object).toJson(QJsonDocument::Compact) + '\n';
//         qDebug() << "sending..." << data;
        m_socket.write(data);
    }

    Purpose::Job* m_job = nullptr;
    QLocalSocket m_socket;
};

int main(int argc, char** argv)
{
#warning make QGuiApplication, consider QCoreApplication?
    QApplication app(argc, argv);

    QString serverName;

    {
        QCommandLineParser parser;
        parser.addOption(QCommandLineOption(QStringLiteral("server"), QStringLiteral("Named socket to connect to"), QStringLiteral("name")));
        parser.addOption(QCommandLineOption(QStringLiteral("pluginPath"), QStringLiteral("Chosen plugin"), QStringLiteral("path")));
        parser.addOption(QCommandLineOption(QStringLiteral("pluginType"), QStringLiteral("Plugin type name "), QStringLiteral("path")));
        parser.addHelpOption();

        parser.process(app);

        serverName = parser.value(QStringLiteral("server"));
        pluginType = parser.value(QStringLiteral("pluginType"));

        const QString path = parser.value(QStringLiteral("pluginPath"));
        if (path.endsWith(QLatin1String("/metadata.json"))) {
            QFileInfo fi(path);
            md = Purpose::createMetaData(path);
        } else {
            md = KPluginMetaData(path);
            Q_ASSERT(md.isValid());
        }
    }

    Communication c(serverName);

    return app.exec();
}

#include "purposeprocess_main.moc"
<|endoftext|>


<commit_before>/* Copyright (c) 2012 Martin M Reed
 * Copyright (c) 2012 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <bb/cascades/Application>
#include <bb/cascades/ForeignWindow>
#include <bb/cascades/Container>
#include <bb/cascades/StackLayout>
#include <bb/cascades/DockLayout>
#include <bb/cascades/DockLayoutProperties>
#include <bb/cascades/Button>
#include <bb/cascades/Label>
#include <bb/cascades/Page>

#include <camera/camera_api.h>
#include <screen/screen.h>
#include <bps/soundplayer.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <libgen.h>

#include "ffcamerasampleapp.hpp"

using namespace bb::cascades;

#define SECOND 1000000
#define VIDEO_WIDTH 288
#define VIDEO_HEIGHT 512
//#define VIDEO_WIDTH 1080
//#define VIDEO_HEIGHT 1920
#define FILENAME (char*)"/accounts/1000/shared/camera/VID_TEST.mpg"

FFCameraSampleApp::FFCameraSampleApp()
        : mCameraHandle(CAMERA_HANDLE_INVALID), record(false)
{
    // create our foreign window
    // Using .id() in the builder is equivalent to mViewfinderWindow->setWindowId()
    mViewfinderWindow = ForeignWindow::create().id(QString("cameraViewfinder"));

    // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby the
    // SCREEN_PROPERTY_SOURCE_SIZE is updated when windows are attached.
    // We don't want this to happen, so we are disabling WindowFrameUpdates.
    // What this means is that if the ForeignWindow geometry is changed, then
    // the underlying screen window properties are not automatically updated to
    // match.  You will have to manually do so by listening for controlFrameChanged
    // signals.  This is outside of the scope of this sample.
    mViewfinderWindow->setWindowFrameUpdateEnabled(false);

    QObject::connect(mViewfinderWindow, SIGNAL(windowAttached(unsigned long,
                    const QString &, const QString &)), this, SLOT(onWindowAttached(unsigned long,
                    const QString &,const QString &)));

    // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby
    // when a window is detached, it's windowHandle is not reset to 0.
    // We need to connect a detach handler to implement a workaround.
    QObject::connect(mViewfinderWindow, SIGNAL(windowDetached(unsigned long,
                    const QString &, const QString &)), this, SLOT(onWindowDetached(unsigned long,
                    const QString &,const QString &)));

    // create a bunch of camera control buttons
    // NOTE: some of these buttons are not initially visible
    mStartFrontButton = Button::create("Front Camera");
    mStartRearButton = Button::create("Rear Camera");
    mStopButton = Button::create("Stop Camera");
    mStopButton->setVisible(false);
    mStartStopButton = Button::create("Record Start");
    mStartStopButton->setVisible(false);

    // connect actions to the buttons
    QObject::connect(mStartFrontButton, SIGNAL(clicked()), this, SLOT(onStartFront()));
    QObject::connect(mStartRearButton, SIGNAL(clicked()), this, SLOT(onStartRear()));
    QObject::connect(mStopButton, SIGNAL(clicked()), this, SLOT(onStopCamera()));
    QObject::connect(mStartStopButton, SIGNAL(clicked()), this, SLOT(onStartStopRecording()));
    mStatusLabel = Label::create("filename");
    mStatusLabel->setVisible(false);

    // using dock layout mainly.  the viewfinder foreign window sits in the center,
    // and the buttons live in their own container at the bottom.
    // a single text label sits at the top of the screen to report recording status.
    Container* container = Container::create().layout(DockLayout::create())
            .add(Container::create().layoutProperties(DockLayoutProperties::create()
            .horizontal(HorizontalAlignment::Center)
            .vertical(VerticalAlignment::Center))
            .add(mViewfinderWindow))
            .add(Container::create().layoutProperties(DockLayoutProperties::create()
            .horizontal(HorizontalAlignment::Left).vertical(VerticalAlignment::Top))
            .add(mStatusLabel))
            .add(Container::create().layoutProperties(DockLayoutProperties::create()
            .horizontal(HorizontalAlignment::Center).vertical(VerticalAlignment::Bottom))
            .layout(StackLayout::create().direction(LayoutDirection::LeftToRight))
            .add(mStartFrontButton)
            .add(mStartRearButton)
            .add(mStartStopButton)
            .add(mStopButton));

    Application::setScene(Page::create().content(container));

    ffc_context = (ffcamera_context*) malloc(sizeof(ffcamera_context));
    memset(ffc_context, 0, sizeof(ffcamera_context));
}

FFCameraSampleApp::~FFCameraSampleApp()
{
    delete mViewfinderWindow;

    free(ffc_context);
    ffc_context = NULL;
}

void FFCameraSampleApp::onWindowAttached(unsigned long handle, const QString &group, const QString &id)
{
    qDebug() << "onWindowAttached: " << handle << ", " << group << ", " << id;
    screen_window_t win = (screen_window_t) handle;

    // set screen properties to mirror if this is the front-facing camera
    int i = (mCameraUnit == CAMERA_UNIT_FRONT);
    screen_set_window_property_iv(win, SCREEN_PROPERTY_MIRROR, &i);

    // put the viewfinder window behind the cascades window
    i = -1;
    screen_set_window_property_iv(win, SCREEN_PROPERTY_ZORDER, &i);

    // make the window visible.  by default, the camera creates an invisible
    // viewfinder, so that the user can decide when and where to place it
    i = 1;
    screen_set_window_property_iv(win, SCREEN_PROPERTY_VISIBLE, &i);

    // There is a bug in ForeignWindow in 10.0.6 which defers window context
    // flushing until some future UI update.  As a result, the window will
    // not actually be visible until someone flushes the context.  This is
    // fixed in the next release.  For now, we will just manually flush the
    // window context.
    screen_context_t ctx;
    screen_get_window_property_pv(win, SCREEN_PROPERTY_CONTEXT, (void**) &ctx);
    screen_flush_context(ctx, 0);
}

void FFCameraSampleApp::onWindowDetached(unsigned long handle, const QString &group, const QString &id)
{
    // There is a bug in ForeignWindow in 10.0.6 whereby the windowHandle is not
    // reset to 0 when a detach event happens.  We must forcefully zero it here
    // in order for a re-attach to work again in the future.
    mViewfinderWindow->setWindowHandle(0);
}

int FFCameraSampleApp::createViewfinder(camera_unit_t cameraUnit, const QString &group, const QString &id)
{
    if (mCameraHandle != CAMERA_HANDLE_INVALID) return EBUSY;

    mCameraUnit = cameraUnit;

    if (camera_open(mCameraUnit, CAMERA_MODE_RW, &mCameraHandle) != CAMERA_EOK) return EIO;

    // configure viewfinder properties so our ForeignWindow can find the resulting screen window
    camera_set_videovf_property( mCameraHandle, CAMERA_IMGPROP_WIN_GROUPID, group.toStdString().c_str());
    camera_set_videovf_property( mCameraHandle, CAMERA_IMGPROP_WIN_ID, id.toStdString().c_str());

    camera_set_videovf_property( mCameraHandle,
            CAMERA_IMGPROP_WIDTH, VIDEO_WIDTH,
            CAMERA_IMGPROP_HEIGHT, VIDEO_HEIGHT);

    camera_set_video_property( mCameraHandle,
            CAMERA_IMGPROP_WIDTH, VIDEO_WIDTH,
            CAMERA_IMGPROP_HEIGHT, VIDEO_HEIGHT);

    if (camera_start_video_viewfinder(mCameraHandle, vf_callback, NULL, this) != CAMERA_EOK)
    {
        camera_close(mCameraHandle);
        mCameraHandle = CAMERA_HANDLE_INVALID;
        return EIO;
    }

    mStartFrontButton->setVisible(false);
    mStartRearButton->setVisible(false);
    mStopButton->setVisible(true);
    mStartStopButton->setText("Start Recording");
    mStartStopButton->setVisible(true);
    mStartStopButton->setEnabled(true);
    return EOK;
}

void FFCameraSampleApp::onStartFront()
{
    if (!mViewfinderWindow) return;
    const QString windowGroup = mViewfinderWindow->windowGroup();
    const QString windowId = mViewfinderWindow->windowId();
    createViewfinder(CAMERA_UNIT_FRONT, windowGroup, windowId);
}

void FFCameraSampleApp::onStartRear()
{
    if (!mViewfinderWindow) return;
    const QString windowGroup = mViewfinderWindow->windowGroup();
    const QString windowId = mViewfinderWindow->windowId();
    createViewfinder(CAMERA_UNIT_REAR, windowGroup, windowId);
}

void FFCameraSampleApp::onStopCamera()
{
    if (mCameraHandle == CAMERA_HANDLE_INVALID) return;

    // NOTE that closing the camera causes the viewfinder to stop.
    // When the viewfinder stops, it's window is destroyed and the
    // ForeignWindow object will emit a windowDetached signal.
    camera_close(mCameraHandle);
    mCameraHandle = CAMERA_HANDLE_INVALID;

    // reset button visibility
    mStartStopButton->setVisible(false);
    mStopButton->setVisible(false);
    mStartFrontButton->setVisible(true);
    mStartRearButton->setVisible(true);
}

void FFCameraSampleApp::onStartStopRecording()
{
    if (mCameraHandle == CAMERA_HANDLE_INVALID) return;

    if (record)
    {
        record = false;

        qDebug() << "stop requested";

        ffcamera_stop(ffc_context);

        mStartStopButton->setText("Start Recording");
        mStopButton->setEnabled(true);
        mStatusLabel->setVisible(false);

        return;
    }

    qDebug() << "start requested";

    struct stat buf;
    if (stat(FILENAME, &buf) != -1)
    {
        fprintf(stderr, "deleting old file...\n");
        remove(FILENAME);
    }

    file = fopen(FILENAME, "wb");

    if (!file)
    {
        fprintf(stderr, "could not open %s: %d: %s\n", FILENAME, errno,strerror(errno));
        exit(1);
        return;
    }

    AVCodecContext *codec_context = NULL;
    ffcamera_default_codec(CODEC_ID_MPEG2VIDEO, 288, 512, &codec_context);

    codec_context->pix_fmt = PIX_FMT_YUV420P;
    codec_context->width = VIDEO_WIDTH;
    codec_context->height = VIDEO_HEIGHT;
    codec_context->bit_rate = 400000;
    codec_context->time_base.num = 1;
    codec_context->time_base.den = 30;
    codec_context->ticks_per_frame = 2;
    codec_context->gop_size = 15;
    codec_context->colorspace = AVCOL_SPC_SMPTE170M;
    codec_context->thread_count = 2;

    ffcamera_init(ffc_context);
    ffcamera_set_close_callback(ffc_context, ffc_context_close, this);
    ffc_context->codec_context = codec_context;
    ffc_context->fd = fileno(file);
    ffcamera_start(ffc_context);

    record = true;

    mStartStopButton->setText("Stop Recording");
    mStopButton->setEnabled(false);
    mStatusLabel->setText(basename(FILENAME));
    mStatusLabel->setVisible(true);
}

void vf_callback(camera_handle_t handle, camera_buffer_t* buf, void* arg)
{
    if (buf->frametype != CAMERA_FRAMETYPE_NV12) return;

    FFCameraSampleApp* app = (FFCameraSampleApp*) arg;
    app->update_fps(buf);
    app->print_fps(buf);

    ffcamera_vfcallback(handle, buf, app->ffc_context);
}

void FFCameraSampleApp::update_fps(camera_buffer_t* buf)
{
    fps.push_back(buf->frametimestamp);
    while (fps.back() - fps.front() > SECOND)
    {
        fps.pop_front();
    }
}

void FFCameraSampleApp::print_fps(camera_buffer_t* buf)
{
    static int64_t frametimestamp = 0;
    if (!frametimestamp || buf->frametimestamp - frametimestamp >= SECOND)
    {
        frametimestamp = buf->frametimestamp;
        qDebug() << "fps[" << fps.size() << "]";
    }
}

void ffc_context_close(ffcamera_context *ffc_context, void *arg)
{
    FFCameraSampleApp* app = (FFCameraSampleApp*) arg;

    ffcamera_close(ffc_context);

    fclose(app->file);
    app->file = NULL;
}
<commit_msg>Scaling up the viewfinder<commit_after>/* Copyright (c) 2012 Martin M Reed
 * Copyright (c) 2012 Research In Motion Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <bb/cascades/Application>
#include <bb/cascades/ForeignWindow>
#include <bb/cascades/Container>
#include <bb/cascades/StackLayout>
#include <bb/cascades/DockLayout>
#include <bb/cascades/DockLayoutProperties>
#include <bb/cascades/Button>
#include <bb/cascades/Label>
#include <bb/cascades/Page>

#include <camera/camera_api.h>
#include <screen/screen.h>
#include <bps/soundplayer.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <libgen.h>

#include "ffcamerasampleapp.hpp"

using namespace bb::cascades;

#define SECOND 1000000
#define VIDEO_WIDTH 288
#define VIDEO_HEIGHT 512
//#define VIDEO_WIDTH 1080
//#define VIDEO_HEIGHT 1920
#define FILENAME (char*)"/accounts/1000/shared/camera/VID_TEST.mpg"

FFCameraSampleApp::FFCameraSampleApp()
        : mCameraHandle(CAMERA_HANDLE_INVALID), record(false)
{
    // create our foreign window
    // Using .id() in the builder is equivalent to mViewfinderWindow->setWindowId()
    mViewfinderWindow = ForeignWindow::create().id(QString("cameraViewfinder"));

    // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby the
    // SCREEN_PROPERTY_SOURCE_SIZE is updated when windows are attached.
    // We don't want this to happen, so we are disabling WindowFrameUpdates.
    // What this means is that if the ForeignWindow geometry is changed, then
    // the underlying screen window properties are not automatically updated to
    // match.  You will have to manually do so by listening for controlFrameChanged
    // signals.  This is outside of the scope of this sample.
    mViewfinderWindow->setWindowFrameUpdateEnabled(false);

    QObject::connect(mViewfinderWindow, SIGNAL(windowAttached(unsigned long,
                    const QString &, const QString &)), this, SLOT(onWindowAttached(unsigned long,
                    const QString &,const QString &)));

    // NOTE that there is a bug in ForeignWindow in 10.0.6 whereby
    // when a window is detached, it's windowHandle is not reset to 0.
    // We need to connect a detach handler to implement a workaround.
    QObject::connect(mViewfinderWindow, SIGNAL(windowDetached(unsigned long,
                    const QString &, const QString &)), this, SLOT(onWindowDetached(unsigned long,
                    const QString &,const QString &)));

    // create a bunch of camera control buttons
    // NOTE: some of these buttons are not initially visible
    mStartFrontButton = Button::create("Front Camera");
    mStartRearButton = Button::create("Rear Camera");
    mStopButton = Button::create("Stop Camera");
    mStopButton->setVisible(false);
    mStartStopButton = Button::create("Record Start");
    mStartStopButton->setVisible(false);

    // connect actions to the buttons
    QObject::connect(mStartFrontButton, SIGNAL(clicked()), this, SLOT(onStartFront()));
    QObject::connect(mStartRearButton, SIGNAL(clicked()), this, SLOT(onStartRear()));
    QObject::connect(mStopButton, SIGNAL(clicked()), this, SLOT(onStopCamera()));
    QObject::connect(mStartStopButton, SIGNAL(clicked()), this, SLOT(onStartStopRecording()));
    mStatusLabel = Label::create("filename");
    mStatusLabel->setVisible(false);

    // using dock layout mainly.  the viewfinder foreign window sits in the center,
    // and the buttons live in their own container at the bottom.
    // a single text label sits at the top of the screen to report recording status.
    Container* container = Container::create().layout(DockLayout::create())
            .add(Container::create().layoutProperties(DockLayoutProperties::create()
            .horizontal(HorizontalAlignment::Center)
            .vertical(VerticalAlignment::Center))
            .add(mViewfinderWindow))
            .add(Container::create().layoutProperties(DockLayoutProperties::create()
            .horizontal(HorizontalAlignment::Left).vertical(VerticalAlignment::Top))
            .add(mStatusLabel))
            .add(Container::create().layoutProperties(DockLayoutProperties::create()
            .horizontal(HorizontalAlignment::Center).vertical(VerticalAlignment::Bottom))
            .layout(StackLayout::create().direction(LayoutDirection::LeftToRight))
            .add(mStartFrontButton)
            .add(mStartRearButton)
            .add(mStartStopButton)
            .add(mStopButton));

    Application::setScene(Page::create().content(container));

    ffc_context = (ffcamera_context*) malloc(sizeof(ffcamera_context));
    memset(ffc_context, 0, sizeof(ffcamera_context));
}

FFCameraSampleApp::~FFCameraSampleApp()
{
    delete mViewfinderWindow;

    free(ffc_context);
    ffc_context = NULL;
}

void FFCameraSampleApp::onWindowAttached(unsigned long handle, const QString &group, const QString &id)
{
    qDebug() << "onWindowAttached: " << handle << ", " << group << ", " << id;
    screen_window_t win = (screen_window_t) handle;

    // set screen properties to mirror if this is the front-facing camera
    int i = (mCameraUnit == CAMERA_UNIT_FRONT);
    screen_set_window_property_iv(win, SCREEN_PROPERTY_MIRROR, &i);

    // put the viewfinder window behind the cascades window
    i = -1;
    screen_set_window_property_iv(win, SCREEN_PROPERTY_ZORDER, &i);

    // scale the viewfinder window to fit the display
    int size[] = {768, 1280};
    screen_set_window_property_iv(win, SCREEN_PROPERTY_SIZE, size);

    // make the window visible.  by default, the camera creates an invisible
    // viewfinder, so that the user can decide when and where to place it
    i = 1;
    screen_set_window_property_iv(win, SCREEN_PROPERTY_VISIBLE, &i);

    // There is a bug in ForeignWindow in 10.0.6 which defers window context
    // flushing until some future UI update.  As a result, the window will
    // not actually be visible until someone flushes the context.  This is
    // fixed in the next release.  For now, we will just manually flush the
    // window context.
    screen_context_t ctx;
    screen_get_window_property_pv(win, SCREEN_PROPERTY_CONTEXT, (void**) &ctx);
    screen_flush_context(ctx, 0);
}

void FFCameraSampleApp::onWindowDetached(unsigned long handle, const QString &group, const QString &id)
{
    // There is a bug in ForeignWindow in 10.0.6 whereby the windowHandle is not
    // reset to 0 when a detach event happens.  We must forcefully zero it here
    // in order for a re-attach to work again in the future.
    mViewfinderWindow->setWindowHandle(0);
}

int FFCameraSampleApp::createViewfinder(camera_unit_t cameraUnit, const QString &group, const QString &id)
{
    if (mCameraHandle != CAMERA_HANDLE_INVALID) return EBUSY;

    mCameraUnit = cameraUnit;

    if (camera_open(mCameraUnit, CAMERA_MODE_RW, &mCameraHandle) != CAMERA_EOK) return EIO;

    // configure viewfinder properties so our ForeignWindow can find the resulting screen window
    camera_set_videovf_property( mCameraHandle, CAMERA_IMGPROP_WIN_GROUPID, group.toStdString().c_str());
    camera_set_videovf_property( mCameraHandle, CAMERA_IMGPROP_WIN_ID, id.toStdString().c_str());

    camera_set_videovf_property( mCameraHandle,
            CAMERA_IMGPROP_WIDTH, VIDEO_WIDTH,
            CAMERA_IMGPROP_HEIGHT, VIDEO_HEIGHT);

    camera_set_video_property( mCameraHandle,
            CAMERA_IMGPROP_WIDTH, VIDEO_WIDTH,
            CAMERA_IMGPROP_HEIGHT, VIDEO_HEIGHT);

    if (camera_start_video_viewfinder(mCameraHandle, vf_callback, NULL, this) != CAMERA_EOK)
    {
        camera_close(mCameraHandle);
        mCameraHandle = CAMERA_HANDLE_INVALID;
        return EIO;
    }

    mStartFrontButton->setVisible(false);
    mStartRearButton->setVisible(false);
    mStopButton->setVisible(true);
    mStartStopButton->setText("Start Recording");
    mStartStopButton->setVisible(true);
    mStartStopButton->setEnabled(true);
    return EOK;
}

void FFCameraSampleApp::onStartFront()
{
    if (!mViewfinderWindow) return;
    const QString windowGroup = mViewfinderWindow->windowGroup();
    const QString windowId = mViewfinderWindow->windowId();
    createViewfinder(CAMERA_UNIT_FRONT, windowGroup, windowId);
}

void FFCameraSampleApp::onStartRear()
{
    if (!mViewfinderWindow) return;
    const QString windowGroup = mViewfinderWindow->windowGroup();
    const QString windowId = mViewfinderWindow->windowId();
    createViewfinder(CAMERA_UNIT_REAR, windowGroup, windowId);
}

void FFCameraSampleApp::onStopCamera()
{
    if (mCameraHandle == CAMERA_HANDLE_INVALID) return;

    // NOTE that closing the camera causes the viewfinder to stop.
    // When the viewfinder stops, it's window is destroyed and the
    // ForeignWindow object will emit a windowDetached signal.
    camera_close(mCameraHandle);
    mCameraHandle = CAMERA_HANDLE_INVALID;

    // reset button visibility
    mStartStopButton->setVisible(false);
    mStopButton->setVisible(false);
    mStartFrontButton->setVisible(true);
    mStartRearButton->setVisible(true);
}

void FFCameraSampleApp::onStartStopRecording()
{
    if (mCameraHandle == CAMERA_HANDLE_INVALID) return;

    if (record)
    {
        record = false;

        qDebug() << "stop requested";

        ffcamera_stop(ffc_context);

        mStartStopButton->setText("Start Recording");
        mStopButton->setEnabled(true);
        mStatusLabel->setVisible(false);

        return;
    }

    qDebug() << "start requested";

    struct stat buf;
    if (stat(FILENAME, &buf) != -1)
    {
        fprintf(stderr, "deleting old file...\n");
        remove(FILENAME);
    }

    file = fopen(FILENAME, "wb");

    if (!file)
    {
        fprintf(stderr, "could not open %s: %d: %s\n", FILENAME, errno,strerror(errno));
        exit(1);
        return;
    }

    AVCodecContext *codec_context = NULL;
    ffcamera_default_codec(CODEC_ID_MPEG2VIDEO, 288, 512, &codec_context);

    codec_context->pix_fmt = PIX_FMT_YUV420P;
    codec_context->width = VIDEO_WIDTH;
    codec_context->height = VIDEO_HEIGHT;
    codec_context->bit_rate = 400000;
    codec_context->time_base.num = 1;
    codec_context->time_base.den = 30;
    codec_context->ticks_per_frame = 2;
    codec_context->gop_size = 15;
    codec_context->colorspace = AVCOL_SPC_SMPTE170M;
    codec_context->thread_count = 2;

    ffcamera_init(ffc_context);
    ffcamera_set_close_callback(ffc_context, ffc_context_close, this);
    ffc_context->codec_context = codec_context;
    ffc_context->fd = fileno(file);
    ffcamera_start(ffc_context);

    record = true;

    mStartStopButton->setText("Stop Recording");
    mStopButton->setEnabled(false);
    mStatusLabel->setText(basename(FILENAME));
    mStatusLabel->setVisible(true);
}

void vf_callback(camera_handle_t handle, camera_buffer_t* buf, void* arg)
{
    if (buf->frametype != CAMERA_FRAMETYPE_NV12) return;

    FFCameraSampleApp* app = (FFCameraSampleApp*) arg;
    app->update_fps(buf);
    app->print_fps(buf);

    ffcamera_vfcallback(handle, buf, app->ffc_context);
}

void FFCameraSampleApp::update_fps(camera_buffer_t* buf)
{
    fps.push_back(buf->frametimestamp);
    while (fps.back() - fps.front() > SECOND)
    {
        fps.pop_front();
    }
}

void FFCameraSampleApp::print_fps(camera_buffer_t* buf)
{
    static int64_t frametimestamp = 0;
    if (!frametimestamp || buf->frametimestamp - frametimestamp >= SECOND)
    {
        frametimestamp = buf->frametimestamp;
        qDebug() << "fps[" << fps.size() << "]";
    }
}

void ffc_context_close(ffcamera_context *ffc_context, void *arg)
{
    FFCameraSampleApp* app = (FFCameraSampleApp*) arg;

    ffcamera_close(ffc_context);

    fclose(app->file);
    app->file = NULL;
}
<|endoftext|>


<commit_before>#include "../src/smiles.h"
#include "../src/fileio/molecules.h"

#include "test.h"

using namespace Helium;

int main()
{
  HeMol mol;

  try {
    parse_smiles("c1ccccc1", mol);
  }
  catch(Smiley::Exception &e) {
    std::cerr << e.what();
  }
  COMPARE(6, mol.numAtoms());
  COMPARE(6, mol.numBonds());
}
<commit_msg>Add more tests for smiles.h<commit_after>#include "../src/smiles.h"
#include "../src/fileio/molecules.h"

#include "test.h"

using namespace Helium;

int main()
{
  HeMol mol;

  hemol_from_smiles("CC", mol);
  COMPARE(2, num_atoms(mol));
  COMPARE(1, num_bonds(mol));
  COMPARE(6, get_element(mol, get_atom(mol, 0)));
  COMPARE(6, get_element(mol, get_atom(mol, 1)));
  COMPARE(1, get_order(mol, get_bond(mol, 0)));

  hemol_from_smiles("C=C", mol);
  COMPARE(2, num_atoms(mol));
  COMPARE(1, num_bonds(mol));
  COMPARE(6, get_element(mol, get_atom(mol, 0)));
  COMPARE(6, get_element(mol, get_atom(mol, 1)));
  COMPARE(2, get_order(mol, get_bond(mol, 0)));
  COMPARE(2, get_bond(mol, 0).order());

  hemol_from_smiles("c1ccccc1", mol);
  COMPARE(6, mol.numAtoms());
  COMPARE(6, mol.numBonds());
}
<|endoftext|>


<commit_before><commit_msg>[functionals.interfaces] modernize static checks<commit_after><|endoftext|>


<commit_before>#include <catch2/catch.hpp>
#include <kangaru/kangaru.hpp>
#include <csignal>

static void abort_handler(int signal)
{
	if (signal == SIGABRT) {
		SUCCEED();
		std::exit(0);
	}
}

#if defined(KGR_KANGARU_TEST_ABSTRACT_ABORT)

TEST_CASE("Should abort when exceptions are disabled", "[noexcept]") {
	std::signal(SIGABRT, abort_handler);
	struct A {};
	struct Abstract : kgr::abstract_service<A> {};

	kgr::container{}.service<Abstract>();
}

#elif KGR_KANGARU_TEST_SUPPLIED_ABORT

TEST_CASE("Should abort when exceptions are disabled", "[noexcept]") {
	std::signal(SIGABRT, abort_handler);
	struct S {};
	struct Supplied : kgr::single_service<S>, kgr::supplied {};

	kgr::container{}.service<Supplied>();
}

#endif
<commit_msg>Simplified disabled exceptions test<commit_after>#include <catch2/catch.hpp>
#include <kangaru/kangaru.hpp>
#include <csignal>

static void abort_handler(int signal)
{
	if (signal == SIGABRT) {
		SUCCEED();
		std::exit(0);
	}
}

TEST_CASE("Should abort when exceptions are disabled", "[noexcept]") {
	std::signal(SIGABRT, abort_handler);

#if defined(KGR_KANGARU_TEST_ABSTRACT_ABORT)
	SECTION("Supplied service error") {
		struct S {};
		struct Supplied : kgr::single_service<S>, kgr::supplied {};

		kgr::container{}.service<Supplied>();
	}
#elif defined(KGR_KANGARU_TEST_SUPPLIED_ABORT)
	SECTION("Abstract service error") {
		struct A {};
		struct Abstract : kgr::abstract_service<A> {};

		kgr::container{}.service<Abstract>();
	}
#else
	#error "Specify a test to run"
#endif
}

<|endoftext|>


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

#ifndef _REGISTRATIONHELPER_CXX_INCLUDED_INDIRECTLY_
#error "don't build this file directly! use dba_reghelper.cxx or dbu_reghelper.cxx instead!"
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using namespace ::rtl;
using namespace ::comphelper;
using namespace ::cppu;

Sequence< OUString >*               OModuleRegistration::s_pImplementationNames = NULL;
Sequence< Sequence< OUString > >*   OModuleRegistration::s_pSupportedServices = NULL;
Sequence< sal_Int64 >*              OModuleRegistration::s_pCreationFunctionPointers = NULL;
Sequence< sal_Int64 >*              OModuleRegistration::s_pFactoryFunctionPointers = NULL;

//--------------------------------------------------------------------------
void OModuleRegistration::registerComponent(
    const OUString& _rImplementationName,
    const Sequence< OUString >& _rServiceNames,
    ComponentInstantiation _pCreateFunction,
    FactoryInstantiation _pFactoryFunction)
{
    if (!s_pImplementationNames)
    {
        OSL_ENSURE(!s_pSupportedServices && !s_pCreationFunctionPointers && !s_pFactoryFunctionPointers,
            "OModuleRegistration::registerComponent : inconsistent state (the pointers (1)) !");
        s_pImplementationNames = new Sequence< OUString >;
        s_pSupportedServices = new Sequence< Sequence< OUString > >;
        s_pCreationFunctionPointers = new Sequence< sal_Int64 >;
        s_pFactoryFunctionPointers = new Sequence< sal_Int64 >;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::registerComponent : inconsistent state (the pointers (2)) !");

    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::registerComponent : inconsistent state !");

    sal_Int32 nOldLen = s_pImplementationNames->getLength();
    s_pImplementationNames->realloc(nOldLen + 1);
    s_pSupportedServices->realloc(nOldLen + 1);
    s_pCreationFunctionPointers->realloc(nOldLen + 1);
    s_pFactoryFunctionPointers->realloc(nOldLen + 1);

    s_pImplementationNames->getArray()[nOldLen] = _rImplementationName;
    s_pSupportedServices->getArray()[nOldLen] = _rServiceNames;
    s_pCreationFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pCreateFunction);
    s_pFactoryFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pFactoryFunction);
}

//--------------------------------------------------------------------------
void OModuleRegistration::revokeComponent(const ::rtl::OUString& _rImplementationName)
{
    if (!s_pImplementationNames)
    {
        OSL_ENSURE(sal_False, "OModuleRegistration::revokeComponent : have no class infos ! Are you sure called this method at the right time ?");
        return;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::revokeComponent : inconsistent state (the pointers) !");
    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::revokeComponent : inconsistent state !");

    sal_Int32 nLen = s_pImplementationNames->getLength();
    const OUString* pImplNames = s_pImplementationNames->getConstArray();
    for (sal_Int32 i=0; i<nLen; ++i, ++pImplNames)
    {
        if (pImplNames->equals(_rImplementationName))
        {
            removeElementAt(*s_pImplementationNames, i);
            removeElementAt(*s_pSupportedServices, i);
            removeElementAt(*s_pCreationFunctionPointers, i);
            removeElementAt(*s_pFactoryFunctionPointers, i);
            break;
        }
    }

    if (s_pImplementationNames->getLength() == 0)
    {
        delete s_pImplementationNames; s_pImplementationNames = NULL;
        delete s_pSupportedServices; s_pSupportedServices = NULL;
        delete s_pCreationFunctionPointers; s_pCreationFunctionPointers = NULL;
        delete s_pFactoryFunctionPointers; s_pFactoryFunctionPointers = NULL;
    }
}

//--------------------------------------------------------------------------
sal_Bool OModuleRegistration::writeComponentInfos(
        const Reference< XMultiServiceFactory >& /*_rxServiceManager*/,
        const Reference< XRegistryKey >& _rxRootKey)
{
    OSL_ENSURE(_rxRootKey.is(), "OModuleRegistration::writeComponentInfos : invalid argument !");

    if (!s_pImplementationNames)
    {
        OSL_ENSURE(sal_False, "OModuleRegistration::writeComponentInfos : have no class infos ! Are you sure called this method at the right time ?");
        return sal_True;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::writeComponentInfos : inconsistent state (the pointers) !");
    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::writeComponentInfos : inconsistent state !");

    sal_Int32 nLen = s_pImplementationNames->getLength();
    const OUString* pImplName = s_pImplementationNames->getConstArray();
    const Sequence< OUString >* pServices = s_pSupportedServices->getConstArray();

    OUString sRootKey("/", 1, RTL_TEXTENCODING_ASCII_US);
    for (sal_Int32 i=0; i<nLen; ++i, ++pImplName, ++pServices)
    {
        OUString aMainKeyName(sRootKey);
        aMainKeyName += *pImplName;
        aMainKeyName += OUString::createFromAscii("/UNO/SERVICES");

        try
        {
            Reference< XRegistryKey >  xNewKey( _rxRootKey->createKey(aMainKeyName) );

            const OUString* pService = pServices->getConstArray();
            for (sal_uInt32 j=0; j<pServices->getLength(); ++j, ++pService)
                xNewKey->createKey(*pService);
        }
        catch(Exception&)
        {
            OSL_ENSURE(sal_False, "OModuleRegistration::writeComponentInfos : something went wrong while creating the keys !");
            return sal_False;
        }
    }

    return sal_True;
}

//--------------------------------------------------------------------------
Reference< XInterface > OModuleRegistration::getComponentFactory(
    const ::rtl::OUString& _rImplementationName,
    const Reference< XMultiServiceFactory >& _rxServiceManager)
{
    OSL_ENSURE(_rxServiceManager.is(), "OModuleRegistration::getComponentFactory : invalid argument (service manager) !");
    OSL_ENSURE(_rImplementationName.getLength(), "OModuleRegistration::getComponentFactory : invalid argument (implementation name) !");

    if (!s_pImplementationNames)
    {
        OSL_ENSURE(sal_False, "OModuleRegistration::getComponentFactory : have no class infos ! Are you sure called this method at the right time ?");
        return NULL;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::getComponentFactory : inconsistent state (the pointers) !");
    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::getComponentFactory : inconsistent state !");

    Reference< XInterface > xReturn;

    sal_Int32 nLen = s_pImplementationNames->getLength();
    const OUString* pImplName = s_pImplementationNames->getConstArray();
    const Sequence< OUString >* pServices = s_pSupportedServices->getConstArray();
    const sal_Int64* pComponentFunction = s_pCreationFunctionPointers->getConstArray();
    const sal_Int64* pFactoryFunction = s_pFactoryFunctionPointers->getConstArray();

    for (sal_Int32 i=0; i<nLen; ++i, ++pImplName, ++pServices, ++pComponentFunction, ++pFactoryFunction)
    {
        if (pImplName->equals(_rImplementationName))
        {
            const FactoryInstantiation FactoryInstantiationFunction = reinterpret_cast<const FactoryInstantiation>(*pFactoryFunction);
            const ComponentInstantiation ComponentInstantiationFunction = reinterpret_cast<const ComponentInstantiation>(*pComponentFunction);

            xReturn = FactoryInstantiationFunction( _rxServiceManager, *pImplName, ComponentInstantiationFunction, *pServices, NULL);
            if (xReturn.is())
            {
                xReturn->acquire();
                return xReturn.get();
            }
        }
    }

    return NULL;
}

<commit_msg>INTEGRATION: CWS insight01 (1.7.134); FILE MERGED 2004/03/30 12:02:30 oj 1.7.134.1: export config settings<commit_after>/*************************************************************************
 *
 *  $RCSfile: registrationhelper.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 15:27:39 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _REGISTRATIONHELPER_CXX_INCLUDED_INDIRECTLY_
#error "don't build this file directly! use dba_reghelper.cxx or dbu_reghelper.cxx instead!"
#endif

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::registry;
using namespace ::rtl;
using namespace ::comphelper;
using namespace ::cppu;

Sequence< OUString >*               OModuleRegistration::s_pImplementationNames = NULL;
Sequence< Sequence< OUString > >*   OModuleRegistration::s_pSupportedServices = NULL;
Sequence< sal_Int64 >*              OModuleRegistration::s_pCreationFunctionPointers = NULL;
Sequence< sal_Int64 >*              OModuleRegistration::s_pFactoryFunctionPointers = NULL;

//--------------------------------------------------------------------------
void OModuleRegistration::registerComponent(
    const OUString& _rImplementationName,
    const Sequence< OUString >& _rServiceNames,
    ComponentInstantiation _pCreateFunction,
    FactoryInstantiation _pFactoryFunction)
{
    if (!s_pImplementationNames)
    {
        OSL_ENSURE(!s_pSupportedServices && !s_pCreationFunctionPointers && !s_pFactoryFunctionPointers,
            "OModuleRegistration::registerComponent : inconsistent state (the pointers (1)) !");
        s_pImplementationNames = new Sequence< OUString >;
        s_pSupportedServices = new Sequence< Sequence< OUString > >;
        s_pCreationFunctionPointers = new Sequence< sal_Int64 >;
        s_pFactoryFunctionPointers = new Sequence< sal_Int64 >;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::registerComponent : inconsistent state (the pointers (2)) !");

    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::registerComponent : inconsistent state !");

    sal_Int32 nOldLen = s_pImplementationNames->getLength();
    s_pImplementationNames->realloc(nOldLen + 1);
    s_pSupportedServices->realloc(nOldLen + 1);
    s_pCreationFunctionPointers->realloc(nOldLen + 1);
    s_pFactoryFunctionPointers->realloc(nOldLen + 1);

    s_pImplementationNames->getArray()[nOldLen] = _rImplementationName;
    s_pSupportedServices->getArray()[nOldLen] = _rServiceNames;
    s_pCreationFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pCreateFunction);
    s_pFactoryFunctionPointers->getArray()[nOldLen] = reinterpret_cast<sal_Int64>(_pFactoryFunction);
}

//--------------------------------------------------------------------------
void OModuleRegistration::revokeComponent(const ::rtl::OUString& _rImplementationName)
{
    if (!s_pImplementationNames)
    {
        OSL_ENSURE(sal_False, "OModuleRegistration::revokeComponent : have no class infos ! Are you sure called this method at the right time ?");
        return;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::revokeComponent : inconsistent state (the pointers) !");
    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::revokeComponent : inconsistent state !");

    sal_Int32 nLen = s_pImplementationNames->getLength();
    const OUString* pImplNames = s_pImplementationNames->getConstArray();
    for (sal_Int32 i=0; i<nLen; ++i, ++pImplNames)
    {
        if (pImplNames->equals(_rImplementationName))
        {
            removeElementAt(*s_pImplementationNames, i);
            removeElementAt(*s_pSupportedServices, i);
            removeElementAt(*s_pCreationFunctionPointers, i);
            removeElementAt(*s_pFactoryFunctionPointers, i);
            break;
        }
    }

    if (s_pImplementationNames->getLength() == 0)
    {
        delete s_pImplementationNames; s_pImplementationNames = NULL;
        delete s_pSupportedServices; s_pSupportedServices = NULL;
        delete s_pCreationFunctionPointers; s_pCreationFunctionPointers = NULL;
        delete s_pFactoryFunctionPointers; s_pFactoryFunctionPointers = NULL;
    }
}

//--------------------------------------------------------------------------
sal_Bool OModuleRegistration::writeComponentInfos(
        const Reference< XMultiServiceFactory >& /*_rxServiceManager*/,
        const Reference< XRegistryKey >& _rxRootKey)
{
    OSL_ENSURE(_rxRootKey.is(), "OModuleRegistration::writeComponentInfos : invalid argument !");

    if (!s_pImplementationNames)
    {
        OSL_ENSURE(sal_False, "OModuleRegistration::writeComponentInfos : have no class infos ! Are you sure called this method at the right time ?");
        return sal_True;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::writeComponentInfos : inconsistent state (the pointers) !");
    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::writeComponentInfos : inconsistent state !");

    sal_Int32 nLen = s_pImplementationNames->getLength();
    const OUString* pImplName = s_pImplementationNames->getConstArray();
    const Sequence< OUString >* pServices = s_pSupportedServices->getConstArray();

    OUString sRootKey("/", 1, RTL_TEXTENCODING_ASCII_US);
    for (sal_Int32 i=0; i<nLen; ++i, ++pImplName, ++pServices)
    {
        OUString aMainKeyName(sRootKey);
        aMainKeyName += *pImplName;
        aMainKeyName += OUString::createFromAscii("/UNO/SERVICES");

        try
        {
            Reference< XRegistryKey >  xNewKey( _rxRootKey->createKey(aMainKeyName) );

            const OUString* pService = pServices->getConstArray();
            for (sal_Int32 j=0; j<pServices->getLength(); ++j, ++pService)
                xNewKey->createKey(*pService);
        }
        catch(Exception&)
        {
            OSL_ENSURE(sal_False, "OModuleRegistration::writeComponentInfos : something went wrong while creating the keys !");
            return sal_False;
        }
    }

    return sal_True;
}

//--------------------------------------------------------------------------
Reference< XInterface > OModuleRegistration::getComponentFactory(
    const ::rtl::OUString& _rImplementationName,
    const Reference< XMultiServiceFactory >& _rxServiceManager)
{
    OSL_ENSURE(_rxServiceManager.is(), "OModuleRegistration::getComponentFactory : invalid argument (service manager) !");
    OSL_ENSURE(_rImplementationName.getLength(), "OModuleRegistration::getComponentFactory : invalid argument (implementation name) !");

    if (!s_pImplementationNames)
    {
        OSL_ENSURE(sal_False, "OModuleRegistration::getComponentFactory : have no class infos ! Are you sure called this method at the right time ?");
        return NULL;
    }
    OSL_ENSURE(s_pImplementationNames && s_pSupportedServices && s_pCreationFunctionPointers && s_pFactoryFunctionPointers,
        "OModuleRegistration::getComponentFactory : inconsistent state (the pointers) !");
    OSL_ENSURE( (s_pImplementationNames->getLength() == s_pSupportedServices->getLength())
                &&  (s_pImplementationNames->getLength() == s_pCreationFunctionPointers->getLength())
                &&  (s_pImplementationNames->getLength() == s_pFactoryFunctionPointers->getLength()),
        "OModuleRegistration::getComponentFactory : inconsistent state !");

    Reference< XInterface > xReturn;

    sal_Int32 nLen = s_pImplementationNames->getLength();
    const OUString* pImplName = s_pImplementationNames->getConstArray();
    const Sequence< OUString >* pServices = s_pSupportedServices->getConstArray();
    const sal_Int64* pComponentFunction = s_pCreationFunctionPointers->getConstArray();
    const sal_Int64* pFactoryFunction = s_pFactoryFunctionPointers->getConstArray();

    for (sal_Int32 i=0; i<nLen; ++i, ++pImplName, ++pServices, ++pComponentFunction, ++pFactoryFunction)
    {
        if (pImplName->equals(_rImplementationName))
        {
            const FactoryInstantiation FactoryInstantiationFunction = reinterpret_cast<const FactoryInstantiation>(*pFactoryFunction);
            const ComponentInstantiation ComponentInstantiationFunction = reinterpret_cast<const ComponentInstantiation>(*pComponentFunction);

            xReturn = FactoryInstantiationFunction( _rxServiceManager, *pImplName, ComponentInstantiationFunction, *pServices, NULL);
            if (xReturn.is())
            {
                xReturn->acquire();
                return xReturn.get();
            }
        }
    }

    return NULL;
}

<|endoftext|>