<commit_before>/*
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "../tests.h"

#include "test_runner.h"
#include "test_stdout_reporter.h"

#include <botan/version.h>
#include <botan/internal/loadstor.h>
#include <botan/internal/cpuid.h>

#if defined(BOTAN_HAS_THREAD_UTILS)
   #include <botan/internal/thread_pool.h>
   #include <botan/internal/rwlock.h>
#endif

namespace Botan_Tests {

Test_Runner::Test_Runner(std::ostream& out) : m_output(out) {}
Test_Runner::~Test_Runner() = default;

namespace {

/*
* This is a fast, simple, deterministic PRNG that's used for running
* the tests. It is not intended to be cryptographically secure.
*/
class Testsuite_RNG final : public Botan::RandomNumberGenerator
   {
   public:
      std::string name() const override { return "Testsuite_RNG"; }

      void clear() override
         {
         m_x = 0;
         }

      bool accepts_input() const override { return true; }

      void add_entropy(const uint8_t data[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            mix(data[i]);
            }
         }

      bool is_seeded() const override
         {
         return true;
         }

      void randomize(uint8_t out[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            out[i] = mix();
            }
         }

      Testsuite_RNG(const std::vector<uint8_t>& seed, uint64_t test_counter)
         {
         m_x = ~test_counter;
         add_entropy(seed.data(), seed.size());
         }
   private:
      uint8_t mix(uint8_t input = 0)
         {
         m_x ^= input;
         m_x *= 0xF2E16957;
         m_x += 0xE50B590F;
         return static_cast<uint8_t>(m_x >> 27);
         }

      uint64_t m_x;
   };

}

bool Test_Runner::run(const Test_Options& opts)
   {
   std::vector<std::string> req = opts.requested_tests();
   const std::set<std::string>& to_skip = opts.skip_tests();

   m_reporters.emplace_back(std::make_unique<StdoutReporter>(opts, output()));

   if(req.empty())
      {
      /*
      If nothing was requested on the command line, run everything. First
      run the "essentials" to smoke test, then everything else in
      alphabetical order.
      */

      std::vector<std::string> default_first = {
         "block", "stream", "hash", "mac", "aead",
         "modes", "kdf", "pbkdf", "hmac_drbg", "util"
      };

      for(const auto& s : default_first)
         {
         if(to_skip.count(s) == 0)
            req.push_back(s);
         }

      std::set<std::string> all_others = Botan_Tests::Test::registered_tests();

      if(opts.pkcs11_lib().empty())
         {
         // do not run pkcs11 tests by default unless pkcs11-lib set
         for(std::set<std::string>::iterator iter = all_others.begin(); iter != all_others.end();)
            {
            if((*iter).find("pkcs11") != std::string::npos)
               {
               iter = all_others.erase(iter);
               }
            else
               {
               ++iter;
               }
            }
         }

      for(const auto& f : req)
         {
         all_others.erase(f);
         }

      for(const std::string& f : to_skip)
         {
         all_others.erase(f);
         }

      req.insert(req.end(), all_others.begin(), all_others.end());
      }
   else if(req.size() == 1 && req.at(0) == "pkcs11")
      {
      req = {"pkcs11-manage", "pkcs11-module", "pkcs11-slot", "pkcs11-session", "pkcs11-object", "pkcs11-rsa",
             "pkcs11-ecdsa", "pkcs11-ecdh", "pkcs11-rng", "pkcs11-x509"
      };
      }
   else
      {
      std::set<std::string> all = Botan_Tests::Test::registered_tests();
      for(auto const& r : req)
         {
         if(all.find(r) == all.end())
            {
            throw Botan_Tests::Test_Error("Unknown test suite: " + r);
            }
         }
      }

   std::vector<uint8_t> seed = Botan::hex_decode(opts.drbg_seed());
   if(seed.empty())
      {
      const uint64_t ts = Botan_Tests::Test::timestamp();
      seed.resize(8);
      Botan::store_be(ts, seed.data());
      }

   for(auto& reporter : m_reporters)
      {
      const std::string cpuid = Botan::CPUID::to_string();
      if(!cpuid.empty())
         reporter->set_property("CPU flags", cpuid);

      if(!opts.pkcs11_lib().empty())
         reporter->set_property("pkcs11 library", opts.pkcs11_lib());

      if(!opts.provider().empty())
         reporter->set_property("provider", opts.provider());

      reporter->set_property("drbg_seed", Botan::hex_encode(seed));
      }

   Botan_Tests::Test::set_test_options(opts);

   for(size_t i = 0; i != opts.test_runs(); ++i)
      {
      auto rng = std::make_unique<Testsuite_RNG>(seed, i);

      Botan_Tests::Test::set_test_rng(std::move(rng));

      for(const auto& reporter : m_reporters)
         {
         reporter->next_test_run();
         }

      const bool passed =
         (opts.test_threads() == 1)
            ? run_tests(req)
            : run_tests_multithreaded(req, opts.test_threads());

      for(const auto& reporter : m_reporters)
         {
         reporter->render();
         }

      if(!passed)
         return false;
      }

   return true;
   }

namespace {

std::vector<Test::Result> run_a_test(const std::string& test_name)
   {
   std::vector<Test::Result> results;

   try
      {
      if(test_name == "simd_32" && Botan::CPUID::has_simd_32() == false)
         {
         results.push_back(Test::Result::Note(test_name, "SIMD not available on this platform"));
         }
      else if(std::unique_ptr<Test> test = Test::get_test(test_name))
         {
         std::vector<Test::Result> test_results = test->run();
         results.insert(results.end(), test_results.begin(), test_results.end());
         }
      else
         {
         results.push_back(Test::Result::Note(test_name, "Test missing or unavailable"));
         }
      }
   catch(std::exception& e)
      {
      results.push_back(Test::Result::Failure(test_name, e.what()));
      }
   catch(...)
      {
      results.push_back(Test::Result::Failure(test_name, "unknown exception"));
      }

   return results;
   }

#if defined(BOTAN_HAS_THREAD_UTILS)

bool needs_serialization(const std::string& test_name)
   {
   if(test_name.substr(0, 6) == "pkcs11")
      return true;
   if(test_name == "block" || test_name == "hash" || test_name == "mac" || test_name == "stream" || test_name == "aead")
      return true;
   if(test_name == "ecc_unit")
      return false;
   return false;
   }

#endif

bool all_passed(const std::vector<Test::Result>& results)
   {
   return std::all_of(results.begin(), results.end(),
                      [](const auto& r) { return r.tests_failed() == 0; });
   }

}

bool Test_Runner::run_tests_multithreaded(const std::vector<std::string>& tests_to_run,
                                          size_t test_threads)
   {
   // If 0 then we let thread pool select the count
   BOTAN_ASSERT_NOMSG(test_threads != 1);

#if !defined(BOTAN_HAS_THREAD_UTILS)
   output() << "Running tests in multiple threads not enabled in this build\n";
   return run_tests(tests_to_run);

#else
   Botan::Thread_Pool pool(test_threads);
   Botan::RWLock rwlock;

   std::vector<std::future<std::vector<Test::Result>>> m_fut_results;

   auto run_test_exclusive = [&](const std::string& test_name) {
      rwlock.lock();
      std::vector<Test::Result> results = run_a_test(test_name);
      rwlock.unlock();
      return results;
   };

   auto run_test_shared = [&](const std::string& test_name) {
      rwlock.lock_shared();
      std::vector<Test::Result> results = run_a_test(test_name);
      rwlock.unlock_shared();
      return results;
   };

   for(auto const& test_name : tests_to_run)
      {
      if(needs_serialization(test_name))
         {
         m_fut_results.push_back(pool.run(run_test_exclusive, test_name));
         }
      else
         {
         m_fut_results.push_back(pool.run(run_test_shared, test_name));
         }
      }

   bool passed = true;
   for(size_t i = 0; i != m_fut_results.size(); ++i)
      {
      const auto results = m_fut_results[i].get();
      for(auto& reporter : m_reporters)
         {
         reporter->record(tests_to_run[i], results);
         }
      passed &= all_passed(results);
      }

   pool.shutdown();

   return passed;
#endif
   }

bool Test_Runner::run_tests(const std::vector<std::string>& tests_to_run)
   {
   bool passed = true;
   for(auto const& test_name : tests_to_run)
      {
      const auto results = run_a_test(test_name);

      for(auto& reporter : m_reporters)
         {
         reporter->record(test_name, results);
         }
      passed &= all_passed(results);
      }

   return passed;
   }

}
<commit_msg>FIX: use scoped locks for mutexes<commit_after>/*
* (C) 2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "../tests.h"

#include "test_runner.h"
#include "test_stdout_reporter.h"

#include <botan/version.h>
#include <botan/internal/loadstor.h>
#include <botan/internal/cpuid.h>

#if defined(BOTAN_HAS_THREAD_UTILS)
   #include <botan/internal/thread_pool.h>
   #include <botan/internal/rwlock.h>
#endif

#include <shared_mutex>

namespace Botan_Tests {

Test_Runner::Test_Runner(std::ostream& out) : m_output(out) {}
Test_Runner::~Test_Runner() = default;

namespace {

/*
* This is a fast, simple, deterministic PRNG that's used for running
* the tests. It is not intended to be cryptographically secure.
*/
class Testsuite_RNG final : public Botan::RandomNumberGenerator
   {
   public:
      std::string name() const override { return "Testsuite_RNG"; }

      void clear() override
         {
         m_x = 0;
         }

      bool accepts_input() const override { return true; }

      void add_entropy(const uint8_t data[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            mix(data[i]);
            }
         }

      bool is_seeded() const override
         {
         return true;
         }

      void randomize(uint8_t out[], size_t len) override
         {
         for(size_t i = 0; i != len; ++i)
            {
            out[i] = mix();
            }
         }

      Testsuite_RNG(const std::vector<uint8_t>& seed, uint64_t test_counter)
         {
         m_x = ~test_counter;
         add_entropy(seed.data(), seed.size());
         }
   private:
      uint8_t mix(uint8_t input = 0)
         {
         m_x ^= input;
         m_x *= 0xF2E16957;
         m_x += 0xE50B590F;
         return static_cast<uint8_t>(m_x >> 27);
         }

      uint64_t m_x;
   };

}

bool Test_Runner::run(const Test_Options& opts)
   {
   std::vector<std::string> req = opts.requested_tests();
   const std::set<std::string>& to_skip = opts.skip_tests();

   m_reporters.emplace_back(std::make_unique<StdoutReporter>(opts, output()));

   if(req.empty())
      {
      /*
      If nothing was requested on the command line, run everything. First
      run the "essentials" to smoke test, then everything else in
      alphabetical order.
      */

      std::vector<std::string> default_first = {
         "block", "stream", "hash", "mac", "aead",
         "modes", "kdf", "pbkdf", "hmac_drbg", "util"
      };

      for(const auto& s : default_first)
         {
         if(to_skip.count(s) == 0)
            req.push_back(s);
         }

      std::set<std::string> all_others = Botan_Tests::Test::registered_tests();

      if(opts.pkcs11_lib().empty())
         {
         // do not run pkcs11 tests by default unless pkcs11-lib set
         for(std::set<std::string>::iterator iter = all_others.begin(); iter != all_others.end();)
            {
            if((*iter).find("pkcs11") != std::string::npos)
               {
               iter = all_others.erase(iter);
               }
            else
               {
               ++iter;
               }
            }
         }

      for(const auto& f : req)
         {
         all_others.erase(f);
         }

      for(const std::string& f : to_skip)
         {
         all_others.erase(f);
         }

      req.insert(req.end(), all_others.begin(), all_others.end());
      }
   else if(req.size() == 1 && req.at(0) == "pkcs11")
      {
      req = {"pkcs11-manage", "pkcs11-module", "pkcs11-slot", "pkcs11-session", "pkcs11-object", "pkcs11-rsa",
             "pkcs11-ecdsa", "pkcs11-ecdh", "pkcs11-rng", "pkcs11-x509"
      };
      }
   else
      {
      std::set<std::string> all = Botan_Tests::Test::registered_tests();
      for(auto const& r : req)
         {
         if(all.find(r) == all.end())
            {
            throw Botan_Tests::Test_Error("Unknown test suite: " + r);
            }
         }
      }

   std::vector<uint8_t> seed = Botan::hex_decode(opts.drbg_seed());
   if(seed.empty())
      {
      const uint64_t ts = Botan_Tests::Test::timestamp();
      seed.resize(8);
      Botan::store_be(ts, seed.data());
      }

   for(auto& reporter : m_reporters)
      {
      const std::string cpuid = Botan::CPUID::to_string();
      if(!cpuid.empty())
         reporter->set_property("CPU flags", cpuid);

      if(!opts.pkcs11_lib().empty())
         reporter->set_property("pkcs11 library", opts.pkcs11_lib());

      if(!opts.provider().empty())
         reporter->set_property("provider", opts.provider());

      reporter->set_property("drbg_seed", Botan::hex_encode(seed));
      }

   Botan_Tests::Test::set_test_options(opts);

   for(size_t i = 0; i != opts.test_runs(); ++i)
      {
      auto rng = std::make_unique<Testsuite_RNG>(seed, i);

      Botan_Tests::Test::set_test_rng(std::move(rng));

      for(const auto& reporter : m_reporters)
         {
         reporter->next_test_run();
         }

      const bool passed =
         (opts.test_threads() == 1)
            ? run_tests(req)
            : run_tests_multithreaded(req, opts.test_threads());

      for(const auto& reporter : m_reporters)
         {
         reporter->render();
         }

      if(!passed)
         return false;
      }

   return true;
   }

namespace {

std::vector<Test::Result> run_a_test(const std::string& test_name)
   {
   std::vector<Test::Result> results;

   try
      {
      if(test_name == "simd_32" && Botan::CPUID::has_simd_32() == false)
         {
         results.push_back(Test::Result::Note(test_name, "SIMD not available on this platform"));
         }
      else if(std::unique_ptr<Test> test = Test::get_test(test_name))
         {
         std::vector<Test::Result> test_results = test->run();
         results.insert(results.end(), test_results.begin(), test_results.end());
         }
      else
         {
         results.push_back(Test::Result::Note(test_name, "Test missing or unavailable"));
         }
      }
   catch(std::exception& e)
      {
      results.push_back(Test::Result::Failure(test_name, e.what()));
      }
   catch(...)
      {
      results.push_back(Test::Result::Failure(test_name, "unknown exception"));
      }

   return results;
   }

#if defined(BOTAN_HAS_THREAD_UTILS)

bool needs_serialization(const std::string& test_name)
   {
   if(test_name.substr(0, 6) == "pkcs11")
      return true;
   if(test_name == "block" || test_name == "hash" || test_name == "mac" || test_name == "stream" || test_name == "aead")
      return true;
   if(test_name == "ecc_unit")
      return false;
   return false;
   }

#endif

bool all_passed(const std::vector<Test::Result>& results)
   {
   return std::all_of(results.begin(), results.end(),
                      [](const auto& r) { return r.tests_failed() == 0; });
   }

}

bool Test_Runner::run_tests_multithreaded(const std::vector<std::string>& tests_to_run,
                                          size_t test_threads)
   {
   // If 0 then we let thread pool select the count
   BOTAN_ASSERT_NOMSG(test_threads != 1);

#if !defined(BOTAN_HAS_THREAD_UTILS)
   output() << "Running tests in multiple threads not enabled in this build\n";
   return run_tests(tests_to_run);

#else
   Botan::Thread_Pool pool(test_threads);
   Botan::RWLock rwlock;

   std::vector<std::future<std::vector<Test::Result>>> m_fut_results;

   auto run_test_exclusive = [&](const std::string& test_name) {
      std::unique_lock lk(rwlock);
      return run_a_test(test_name);
   };

   auto run_test_shared = [&](const std::string& test_name) {
      std::shared_lock lk(rwlock);
      return run_a_test(test_name);
   };

   for(auto const& test_name : tests_to_run)
      {
      if(needs_serialization(test_name))
         {
         m_fut_results.push_back(pool.run(run_test_exclusive, test_name));
         }
      else
         {
         m_fut_results.push_back(pool.run(run_test_shared, test_name));
         }
      }

   bool passed = true;
   for(size_t i = 0; i != m_fut_results.size(); ++i)
      {
      const auto results = m_fut_results[i].get();
      for(auto& reporter : m_reporters)
         {
         reporter->record(tests_to_run[i], results);
         }
      passed &= all_passed(results);
      }

   pool.shutdown();

   return passed;
#endif
   }

bool Test_Runner::run_tests(const std::vector<std::string>& tests_to_run)
   {
   bool passed = true;
   for(auto const& test_name : tests_to_run)
      {
      const auto results = run_a_test(test_name);

      for(auto& reporter : m_reporters)
         {
         reporter->record(test_name, results);
         }
      passed &= all_passed(results);
      }

   return passed;
   }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textparagraphpropertiescontext.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
#define OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX

#include <list>

#include <com/sun/star/style/TabStop.hpp>
#include "oox/drawingml/textparagraphproperties.hxx"
#include "oox/drawingml/textspacing.hxx"
#include "oox/core/contexthandler.hxx"

namespace oox { namespace drawingml {

class TextParagraphPropertiesContext : public ::oox::core::ContextHandler
{
public:
    TextParagraphPropertiesContext( ::oox::core::ContextHandler& rParent,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& rXAttributes,
            TextParagraphProperties& rTextParagraphProperties );
    ~TextParagraphPropertiesContext();

    virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);

protected:
    TextParagraphProperties& mrTextParagraphProperties;
    TextSpacing     maLineSpacing;
    TextSpacing&    mrSpaceBefore;
    TextSpacing&    mrSpaceAfter;
    BulletList&     mrBulletList;
    ::std::list< ::com::sun::star::style::TabStop >  maTabList;
};

} }

#endif  //  OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
<commit_msg>INTEGRATION: CWS impress146 (1.4.14); FILE MERGED 2008/07/02 14:24:06 sj 1.4.14.1: #i90625# taking care of api changes<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: textparagraphpropertiescontext.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
#define OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX

#include <list>

#include <com/sun/star/style/TabStop.hpp>
#include "oox/drawingml/textparagraphproperties.hxx"
#include "oox/drawingml/textspacing.hxx"
#include "oox/core/contexthandler.hxx"

namespace oox { namespace drawingml {

class TextParagraphPropertiesContext : public ::oox::core::ContextHandler
{
public:
    TextParagraphPropertiesContext( ::oox::core::ContextHandler& rParent,
        const com::sun::star::uno::Reference< com::sun::star::xml::sax::XFastAttributeList >& rXAttributes,
            TextParagraphProperties& rTextParagraphProperties );
    ~TextParagraphPropertiesContext();

    virtual void SAL_CALL endFastElement( ::sal_Int32 Element ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException);

protected:
    TextParagraphProperties& mrTextParagraphProperties;
    TextSpacing     maLineSpacing;
    TextSpacing&    mrSpaceBefore;
    TextSpacing&    mrSpaceAfter;
    BulletList&     mrBulletList;
    ::std::list< ::com::sun::star::style::TabStop >  maTabList;
    FillPropertiesPtr mpFillPropertiesPtr;
};

} }

#endif  //  OOX_DRAWINGML_TEXTPARAGRAPHPROPERTIESCONTEXT_HXX
<|endoftext|>


<commit_before>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>

#include "../log.h"
#include "../pow.h"

namespace
{
  SUITE(test_maths)
  {
    //*************************************************************************
    TEST(test_log_0_base)
    {
      int actual;

      actual = etl::log<0, 2>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log<0, 10>::value;
      CHECK_EQUAL(0, actual);
    }

    //*************************************************************************
    TEST(test_log_1_base)
    {
      int actual;

      actual = etl::log<1, 2>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log<1, 10>::value;
      CHECK_EQUAL(0, actual);
    }

    //*************************************************************************
    TEST(test_log_10_base)
    {
      int actual;

      actual = etl::log<10, 2>::value;
      CHECK_EQUAL(3, actual);

      actual = etl::log<10, 10>::value;
      CHECK_EQUAL(1, actual);
    }

    //*************************************************************************
    TEST(test_log_100_base)
    {
      int actual;

      actual = etl::log<100, 2>::value;
      CHECK_EQUAL(6, actual);

      actual = etl::log<100, 10>::value;
      CHECK_EQUAL(2, actual);
    }

    //*************************************************************************
    TEST(test_log_2)
    {
      int actual;

      actual = etl::log2<0>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log2<1>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log2<10>::value;
      CHECK_EQUAL(3, actual);

      actual = etl::log2<100>::value;
      CHECK_EQUAL(6, actual);
    }

    //*************************************************************************
    TEST(test_log_10)
    {
      int actual;

      actual = etl::log10<0>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log10<1>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log10<10>::value;
      CHECK_EQUAL(1, actual);

      actual = etl::log10<100>::value;
      CHECK_EQUAL(2, actual);

      actual = etl::log10<100>::value;
      CHECK_EQUAL(2, actual);
    }

    //*************************************************************************
    TEST(test_pow)
    {
      int actual;

      // 2^1
      actual = etl::pow<2, 1>::value;
      CHECK_EQUAL(2, actual);

      // 3^2
      actual = etl::pow<3, 2>::value;
      CHECK_EQUAL(9, actual);

      // 4^3
      actual = etl::pow<4, 3>::value;
      CHECK_EQUAL(64, actual);

      // 5^4
      actual = etl::pow<5, 4>::value;
      CHECK_EQUAL(625, actual);

      // 6^5
      actual = etl::pow<6, 5>::value;
      CHECK_EQUAL(7776, actual);

      // 7^6
      actual = etl::pow<7, 6>::value;
      CHECK_EQUAL(117649, actual);

      // 8^7
      actual = etl::pow<8, 7>::value;
      CHECK_EQUAL(2097152, actual);

      // 9^8
      actual = etl::pow<9, 8>::value;
      CHECK_EQUAL(43046721, actual);

      // 10^9
      actual = etl::pow<10, 9>::value;
      CHECK_EQUAL(1000000000, actual);
    }
  };
}<commit_msg>Changed pow to power, added Fibbonacci<commit_after>/******************************************************************************
The MIT License(MIT)

Embedded Template Library.

Copyright(c) 2014 jwellbelove

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/

#include <UnitTest++/UnitTest++.h>

#include "../log.h"
#include "../power.h"
#include "../fibonacci.h"
#include "../factorial.h"

namespace
{
  SUITE(test_maths)
  {
    //*************************************************************************
    TEST(test_log_0_base)
    {
      int actual;

      actual = etl::log<0, 2>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log<0, 10>::value;
      CHECK_EQUAL(0, actual);
    }

    //*************************************************************************
    TEST(test_log_1_base)
    {
      int actual;

      actual = etl::log<1, 2>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log<1, 10>::value;
      CHECK_EQUAL(0, actual);
    }

    //*************************************************************************
    TEST(test_log_10_base)
    {
      int actual;

      actual = etl::log<10, 2>::value;
      CHECK_EQUAL(3, actual);

      actual = etl::log<10, 10>::value;
      CHECK_EQUAL(1, actual);
    }

    //*************************************************************************
    TEST(test_log_100_base)
    {
      int actual;

      actual = etl::log<100, 2>::value;
      CHECK_EQUAL(6, actual);

      actual = etl::log<100, 10>::value;
      CHECK_EQUAL(2, actual);
    }

    //*************************************************************************
    TEST(test_log_2)
    {
      int actual;

      actual = etl::log2<0>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log2<1>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log2<10>::value;
      CHECK_EQUAL(3, actual);

      actual = etl::log2<100>::value;
      CHECK_EQUAL(6, actual);
    }

    //*************************************************************************
    TEST(test_log_10)
    {
      int actual;

      actual = etl::log10<0>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log10<1>::value;
      CHECK_EQUAL(0, actual);

      actual = etl::log10<10>::value;
      CHECK_EQUAL(1, actual);

      actual = etl::log10<100>::value;
      CHECK_EQUAL(2, actual);

      actual = etl::log10<100>::value;
      CHECK_EQUAL(2, actual);
    }

    //*************************************************************************
    TEST(test_pow)
    {
      int actual;

      // 2^1
      actual = etl::power<2, 1>::value;
      CHECK_EQUAL(2, actual);

      // 3^2
      actual = etl::power<3, 2>::value;
      CHECK_EQUAL(9, actual);

      // 4^3
      actual = etl::power<4, 3>::value;
      CHECK_EQUAL(64, actual);

      // 5^4
      actual = etl::power<5, 4>::value;
      CHECK_EQUAL(625, actual);

      // 6^5
      actual = etl::power<6, 5>::value;
      CHECK_EQUAL(7776, actual);

      // 7^6
      actual = etl::power<7, 6>::value;
      CHECK_EQUAL(117649, actual);

      // 8^7
      actual = etl::power<8, 7>::value;
      CHECK_EQUAL(2097152, actual);

      // 9^8
      actual = etl::power<9, 8>::value;
      CHECK_EQUAL(43046721, actual);

      // 10^9
      actual = etl::power<10, 9>::value;
      CHECK_EQUAL(1000000000, actual);
    }

    //*************************************************************************
    TEST(test_fibbonacci)
    {
      CHECK_EQUAL(0,          (size_t)etl::fibonacci<0>::value);
      CHECK_EQUAL(1,          (size_t)etl::fibonacci<1>::value);
      CHECK_EQUAL(1,          (size_t)etl::fibonacci<2>::value);
      CHECK_EQUAL(2,          (size_t)etl::fibonacci<3>::value);
      CHECK_EQUAL(3,          (size_t)etl::fibonacci<4>::value);
      CHECK_EQUAL(5,          (size_t)etl::fibonacci<5>::value);
      CHECK_EQUAL(8,          (size_t)etl::fibonacci<6>::value);
      CHECK_EQUAL(13,         (size_t)etl::fibonacci<7>::value);
      CHECK_EQUAL(21,         (size_t)etl::fibonacci<8>::value);
      CHECK_EQUAL(34,         (size_t)etl::fibonacci<9>::value);
      CHECK_EQUAL(55,         (size_t)etl::fibonacci<10>::value);
      CHECK_EQUAL(89,         (size_t)etl::fibonacci<11>::value);
      CHECK_EQUAL(144,        (size_t)etl::fibonacci<12>::value);
      CHECK_EQUAL(233,        (size_t)etl::fibonacci<13>::value);
      CHECK_EQUAL(377,        (size_t)etl::fibonacci<14>::value);
      CHECK_EQUAL(610,        (size_t)etl::fibonacci<15>::value);
      CHECK_EQUAL(987,        (size_t)etl::fibonacci<16>::value);
      CHECK_EQUAL(1597,       (size_t)etl::fibonacci<17>::value);
      CHECK_EQUAL(2584,       (size_t)etl::fibonacci<18>::value);
      CHECK_EQUAL(4181,       (size_t)etl::fibonacci<19>::value);
      CHECK_EQUAL(6765,       (size_t)etl::fibonacci<20>::value);
      CHECK_EQUAL(10946,      (size_t)etl::fibonacci<21>::value);
      CHECK_EQUAL(17711,      (size_t)etl::fibonacci<22>::value);
      CHECK_EQUAL(28657,      (size_t)etl::fibonacci<23>::value);
      CHECK_EQUAL(46368,      (size_t)etl::fibonacci<24>::value);
      CHECK_EQUAL(75025,      (size_t)etl::fibonacci<25>::value);
      CHECK_EQUAL(121393,     (size_t)etl::fibonacci<26>::value);
      CHECK_EQUAL(196418,     (size_t)etl::fibonacci<27>::value);
      CHECK_EQUAL(317811,     (size_t)etl::fibonacci<28>::value);
      CHECK_EQUAL(514229,     (size_t)etl::fibonacci<29>::value);
      CHECK_EQUAL(832040,     (size_t)etl::fibonacci<30>::value);
      CHECK_EQUAL(1346269,    (size_t)etl::fibonacci<31>::value);
      CHECK_EQUAL(2178309,    (size_t)etl::fibonacci<32>::value);
      CHECK_EQUAL(3524578,    (size_t)etl::fibonacci<33>::value);
      CHECK_EQUAL(5702887,    (size_t)etl::fibonacci<34>::value);
      CHECK_EQUAL(9227465,    (size_t)etl::fibonacci<35>::value);
      CHECK_EQUAL(14930352,   (size_t)etl::fibonacci<36>::value);
      CHECK_EQUAL(24157817,   (size_t)etl::fibonacci<37>::value);
      CHECK_EQUAL(39088169,   (size_t)etl::fibonacci<38>::value);
      CHECK_EQUAL(63245986,   (size_t)etl::fibonacci<39>::value);
      CHECK_EQUAL(102334155,  (size_t)etl::fibonacci<40>::value);
      CHECK_EQUAL(165580141,  (size_t)etl::fibonacci<41>::value);
      CHECK_EQUAL(267914296,  (size_t)etl::fibonacci<42>::value);
      CHECK_EQUAL(433494437,  (size_t)etl::fibonacci<43>::value);
      CHECK_EQUAL(701408733,  (size_t)etl::fibonacci<44>::value);
      CHECK_EQUAL(1134903170, (size_t)etl::fibonacci<45>::value);
      CHECK_EQUAL(1836311903, (size_t)etl::fibonacci<46>::value);
      CHECK_EQUAL(2971215073, (size_t)etl::fibonacci<47>::value);
    }

    TEST(test_factorial)
    {
      CHECK_EQUAL(1,         (size_t)etl::factorial<0>::value);
      CHECK_EQUAL(1,         (size_t)etl::factorial<1>::value);
      CHECK_EQUAL(2,         (size_t)etl::factorial<2>::value);
      CHECK_EQUAL(6,         (size_t)etl::factorial<3>::value);
      CHECK_EQUAL(24,        (size_t)etl::factorial<4>::value);
      CHECK_EQUAL(120,       (size_t)etl::factorial<5>::value);
      CHECK_EQUAL(720,       (size_t)etl::factorial<6>::value);
      CHECK_EQUAL(5040,      (size_t)etl::factorial<7>::value);
      CHECK_EQUAL(40320,     (size_t)etl::factorial<8>::value);
      CHECK_EQUAL(362880,    (size_t)etl::factorial<9>::value);
      CHECK_EQUAL(3628800,   (size_t)etl::factorial<10>::value);
      CHECK_EQUAL(39916800,  (size_t)etl::factorial<11>::value);
      CHECK_EQUAL(479001600, (size_t)etl::factorial<12>::value);
    }
  };
}<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Broker RPC Client implementation.

#include "ceee/ie/broker/broker_rpc_client.h"

#include <atlbase.h>
#include "base/lock.h"
#include "base/logging.h"
#include "base/tuple.h"
#include "base/win/scoped_comptr.h"
#include "broker_lib.h"  // NOLINT
#include "broker_rpc_lib.h"  // NOLINT
#include "ceee/common/com_utils.h"
#include "ceee/ie/broker/broker_rpc_utils.h"

namespace {

void LogRpcException(const char* str, unsigned int exception_code) {
  LOG(ERROR) << str << com::LogWe(exception_code);
}

HRESULT BindRpc(std::wstring endpoint, RPC_BINDING_HANDLE* binding_handle) {
  DCHECK(binding_handle != NULL);
  std::wstring protocol = kRpcProtocol;
  DCHECK(!protocol.empty());
  DCHECK(!endpoint.empty());
  if (protocol.empty() || endpoint.empty() || binding_handle == NULL)
    return E_INVALIDARG;

  RPC_BINDING_HANDLE tmp_binding_handle = NULL;

  // TODO(vitalybuka@google.com): There's no guarantee (aside from name
  // uniqueness) that it will connect to an endpoint created by the same user.
  // Hint: The missing invocation is RpcBindingSetAuthInfoEx.
  VLOG(1) << "Connecting to RPC server. Endpoint: " << endpoint;
  RPC_WSTR string_binding = NULL;
  // Create binding string for given end point.
  RPC_STATUS status = ::RpcStringBindingCompose(
      NULL,
      reinterpret_cast<RPC_WSTR>(&protocol[0]),
      NULL,
      reinterpret_cast<RPC_WSTR>(&endpoint[0]),
      NULL,
      &string_binding);

  if (RPC_S_OK == status) {
    // Create binding from just generated binding string. Binding handle should
    // be used for PRC calls.
    status = ::RpcBindingFromStringBinding(string_binding, &tmp_binding_handle);
    ::RpcStringFree(&string_binding);
    if (RPC_S_OK == status) {
      VLOG(1) << "RPC client is connected. Endpoint: " << endpoint;
      *binding_handle = tmp_binding_handle;
      return S_OK;
    } else {
      LogRpcException("Failed to bind. RPC_STATUS:", status);
    }
  } else {
    LogRpcException("Failed to compose binding string. RPC_STATUS:", status);
  }
  return RPC_E_FAULT;
}

int HandleRpcException(unsigned int rpc_exception_code) {
  switch (rpc_exception_code) {
    case STATUS_ACCESS_VIOLATION:
    case STATUS_DATATYPE_MISALIGNMENT:
    case STATUS_PRIVILEGED_INSTRUCTION:
    case STATUS_BREAKPOINT:
    case STATUS_STACK_OVERFLOW:
    case STATUS_IN_PAGE_ERROR:
    case STATUS_GUARD_PAGE_VIOLATION:
      return EXCEPTION_CONTINUE_SEARCH;
    default:
      break;
  }
  return EXCEPTION_EXECUTE_HANDLER;
}

}  // namespace

BrokerRpcClient::BrokerRpcClient(bool allow_restarts)
    : context_(0),
      binding_handle_(NULL),
      allow_restarts_(allow_restarts) {
}

BrokerRpcClient::~BrokerRpcClient() {
  Disconnect();
}

void BrokerRpcClient::LockContext() {
  RpcTryExcept {
    context_ = BrokerRpcClient_Connect(binding_handle_);
  } RpcExcept(HandleRpcException(RpcExceptionCode())) {
    LogRpcException("RPC error in LockContext", RpcExceptionCode());
  } RpcEndExcept
}

void BrokerRpcClient::ReleaseContext() {
  RpcTryExcept {
    BrokerRpcClient_Disconnect(binding_handle_, &context_);
  } RpcExcept(HandleRpcException(RpcExceptionCode())) {
    LogRpcException("RPC error in ReleaseContext", RpcExceptionCode());
  } RpcEndExcept
}

HRESULT BrokerRpcClient::StartServer(IUnknown** server) {
  base::win::ScopedComPtr<IUnknown> broker;
  // TODO(vitalybuka@google.com): Start broker without COM after the last
  // COM interface is removed.
  HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
  LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
  if (FAILED(hr))
    return hr;
  *server = broker.Detach();
  return S_OK;
}

HRESULT BrokerRpcClient::Connect(bool start_server) {
  if (is_connected())
    return S_OK;

  // Keep alive until RPC is connected.
  base::win::ScopedComPtr<IUnknown> broker;
  if (start_server) {
    HRESULT hr = StartServer(broker.Receive());
    if (FAILED(hr))
      return hr;
  }

  if (SUCCEEDED(BindRpc(GetRpcEndpointAddress(), &binding_handle_)))
    LockContext();

  if (!is_connected()) {
    Disconnect();
    return RPC_E_FAULT;
  }
  return S_OK;
}

void BrokerRpcClient::Disconnect() {
  if (context_ != NULL)
    ReleaseContext();
  if (binding_handle_ != NULL) {
    RPC_STATUS status = ::RpcBindingFree(&binding_handle_);
    LOG_IF(WARNING, RPC_S_OK != status) <<
        "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status);
  }
}

template<class Function, class Params>
HRESULT BrokerRpcClient::RunRpc(bool allow_restart,
                                Function rpc_function,
                                const Params& params) {
  DCHECK(rpc_function);
  if (!is_connected())
    return RPC_E_FAULT;
  RpcTryExcept {
    DispatchToFunction(rpc_function, params);
    return S_OK;
  } RpcExcept(HandleRpcException(RpcExceptionCode())) {
    LogRpcException("RPC error in RunRpc", RpcExceptionCode());

    if (allow_restart &&
        RPC_S_OK != ::RpcMgmtIsServerListening(binding_handle_)) {
      Disconnect();
      if (SUCCEEDED(Connect(true))) {
        return RunRpc(false, rpc_function, params);
      }
    }
    return RPC_E_FAULT;
  } RpcEndExcept
}

HRESULT BrokerRpcClient::FireEvent(const char* event_name,
                                   const char* event_args) {
  return RunRpc(allow_restarts_,
                &BrokerRpcClient_FireEvent,
                MakeRefTuple(binding_handle_, context_, event_name,
                             event_args));
}

HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) {
  return RunRpc(allow_restarts_,
                &BrokerRpcClient_SendUmaHistogramTimes,
                MakeRefTuple(binding_handle_, name, sample));
}

HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name,
                                              int sample,
                                              int min,
                                              int max,
                                              int bucket_count) {
  return RunRpc(allow_restarts_,
                &BrokerRpcClient_SendUmaHistogramData,
                MakeRefTuple(binding_handle_, name, sample, min, max,
                          bucket_count));
}
<commit_msg>Avoid unwind in function using __try<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Broker RPC Client implementation.

#include "ceee/ie/broker/broker_rpc_client.h"

#include <atlbase.h>
#include "base/lock.h"
#include "base/logging.h"
#include "base/tuple.h"
#include "base/win/scoped_comptr.h"
#include "broker_lib.h"  // NOLINT
#include "broker_rpc_lib.h"  // NOLINT
#include "ceee/common/com_utils.h"
#include "ceee/ie/broker/broker_rpc_utils.h"

namespace {

// Avoid using objects requiring unwind in functions that use __try.
void LogRpcException(const char* str, unsigned int exception_code) {
  LOG(ERROR) << str << com::LogWe(exception_code);
}

// Avoid using objects requiring unwind in functions that use __try.
void RpcDcheck(const char* message) {
  NOTREACHED() << message;
}

HRESULT BindRpc(std::wstring endpoint, RPC_BINDING_HANDLE* binding_handle) {
  DCHECK(binding_handle != NULL);
  std::wstring protocol = kRpcProtocol;
  DCHECK(!protocol.empty());
  DCHECK(!endpoint.empty());
  if (protocol.empty() || endpoint.empty() || binding_handle == NULL)
    return E_INVALIDARG;

  RPC_BINDING_HANDLE tmp_binding_handle = NULL;

  // TODO(vitalybuka@google.com): There's no guarantee (aside from name
  // uniqueness) that it will connect to an endpoint created by the same user.
  // Hint: The missing invocation is RpcBindingSetAuthInfoEx.
  VLOG(1) << "Connecting to RPC server. Endpoint: " << endpoint;
  RPC_WSTR string_binding = NULL;
  // Create binding string for given end point.
  RPC_STATUS status = ::RpcStringBindingCompose(
      NULL,
      reinterpret_cast<RPC_WSTR>(&protocol[0]),
      NULL,
      reinterpret_cast<RPC_WSTR>(&endpoint[0]),
      NULL,
      &string_binding);

  if (RPC_S_OK == status) {
    // Create binding from just generated binding string. Binding handle should
    // be used for PRC calls.
    status = ::RpcBindingFromStringBinding(string_binding, &tmp_binding_handle);
    ::RpcStringFree(&string_binding);
    if (RPC_S_OK == status) {
      VLOG(1) << "RPC client is connected. Endpoint: " << endpoint;
      *binding_handle = tmp_binding_handle;
      return S_OK;
    } else {
      LogRpcException("Failed to bind. RPC_STATUS:", status);
    }
  } else {
    LogRpcException("Failed to compose binding string. RPC_STATUS:", status);
  }
  return RPC_E_FAULT;
}

int HandleRpcException(unsigned int rpc_exception_code) {
  switch (rpc_exception_code) {
    case STATUS_ACCESS_VIOLATION:
    case STATUS_DATATYPE_MISALIGNMENT:
    case STATUS_PRIVILEGED_INSTRUCTION:
    case STATUS_BREAKPOINT:
    case STATUS_STACK_OVERFLOW:
    case STATUS_IN_PAGE_ERROR:
    case STATUS_GUARD_PAGE_VIOLATION:
      return EXCEPTION_CONTINUE_SEARCH;
    default:
      break;
  }
  return EXCEPTION_EXECUTE_HANDLER;
}

}  // namespace

BrokerRpcClient::BrokerRpcClient(bool allow_restarts)
    : context_(0),
      binding_handle_(NULL),
      allow_restarts_(allow_restarts) {
}

BrokerRpcClient::~BrokerRpcClient() {
  Disconnect();
}

void BrokerRpcClient::LockContext() {
  RpcTryExcept {
    context_ = BrokerRpcClient_Connect(binding_handle_);
  } RpcExcept(HandleRpcException(RpcExceptionCode())) {
    LogRpcException("RPC error in LockContext", RpcExceptionCode());
  } RpcEndExcept
}

void BrokerRpcClient::ReleaseContext() {
  RpcTryExcept {
    BrokerRpcClient_Disconnect(binding_handle_, &context_);
  } RpcExcept(HandleRpcException(RpcExceptionCode())) {
    LogRpcException("RPC error in ReleaseContext", RpcExceptionCode());
  } RpcEndExcept
}

HRESULT BrokerRpcClient::StartServer(IUnknown** server) {
  base::win::ScopedComPtr<IUnknown> broker;
  // TODO(vitalybuka@google.com): Start broker without COM after the last
  // COM interface is removed.
  HRESULT hr = broker.CreateInstance(CLSID_CeeeBroker);
  LOG_IF(ERROR, FAILED(hr)) << "Failed to create broker. " << com::LogHr(hr);
  if (FAILED(hr))
    return hr;
  *server = broker.Detach();
  return S_OK;
}

HRESULT BrokerRpcClient::Connect(bool start_server) {
  if (is_connected())
    return S_OK;

  // Keep alive until RPC is connected.
  base::win::ScopedComPtr<IUnknown> broker;
  if (start_server) {
    HRESULT hr = StartServer(broker.Receive());
    if (FAILED(hr))
      return hr;
  }

  if (SUCCEEDED(BindRpc(GetRpcEndpointAddress(), &binding_handle_)))
    LockContext();

  if (!is_connected()) {
    Disconnect();
    return RPC_E_FAULT;
  }
  return S_OK;
}

void BrokerRpcClient::Disconnect() {
  if (context_ != NULL)
    ReleaseContext();
  if (binding_handle_ != NULL) {
    RPC_STATUS status = ::RpcBindingFree(&binding_handle_);
    LOG_IF(WARNING, RPC_S_OK != status) <<
        "Failed to unbind. RPC_STATUS=0x" << com::LogWe(status);
  }
}

template<class Function, class Params>
HRESULT BrokerRpcClient::RunRpc(bool allow_restart,
                                Function rpc_function,
                                const Params& params) {
  if (!rpc_function) {
    RpcDcheck("rpc_function is NULL");
  }
  if (!is_connected())
    return RPC_E_FAULT;
  RpcTryExcept {
    DispatchToFunction(rpc_function, params);
    return S_OK;
  } RpcExcept(HandleRpcException(RpcExceptionCode())) {
    LogRpcException("RPC error in RunRpc", RpcExceptionCode());

    if (allow_restart &&
        RPC_S_OK != ::RpcMgmtIsServerListening(binding_handle_)) {
      Disconnect();
      if (SUCCEEDED(Connect(true))) {
        return RunRpc(false, rpc_function, params);
      }
    }
    return RPC_E_FAULT;
  } RpcEndExcept
}

HRESULT BrokerRpcClient::FireEvent(const char* event_name,
                                   const char* event_args) {
  return RunRpc(allow_restarts_,
                &BrokerRpcClient_FireEvent,
                MakeRefTuple(binding_handle_, context_, event_name,
                             event_args));
}

HRESULT BrokerRpcClient::SendUmaHistogramTimes(const char* name, int sample) {
  return RunRpc(allow_restarts_,
                &BrokerRpcClient_SendUmaHistogramTimes,
                MakeRefTuple(binding_handle_, name, sample));
}

HRESULT BrokerRpcClient::SendUmaHistogramData(const char* name,
                                              int sample,
                                              int min,
                                              int max,
                                              int bucket_count) {
  return RunRpc(allow_restarts_,
                &BrokerRpcClient_SendUmaHistogramData,
                MakeRefTuple(binding_handle_, name, sample, min, max,
                          bucket_count));
}
<|endoftext|>


<commit_before>#include <VertexAttributeBuffer.h>

void GLVertexAttributeBuffer::toGPU(const void* data, const size_t size)
{
	if (bufferId.value == 0)
	{
		Init();
	}

	glBindBuffer(GL_ARRAY_BUFFER, bufferId.value);

	if (m_maxSize < size) {
		//grow buffer and load all data
		glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
	}
	else {
		//load all data
		glBufferSubData(GL_ARRAY_BUFFER, 0, size, data);
	}
	m_maxSize = size;

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void MatrixVertexAttribute::SendToGPU(const IHgGPUBuffer* bufferObject)
{
	m_attributeBuffer.toGPU(bufferObject->getBufferPtr(), bufferObject->sizeBytes());
}

void InvalidAttributeError(const HgShader& shader, const std::string& name)
{
	auto ss = shader.sourceStruct();
	fprintf(stderr, "Invalid Attribute: %s (shader %s)\n", name.c_str(), ss->vert_file_path.c_str());
}

void MatrixVertexAttribute::Setup(const Instancing::InstancingMetaData& imd, const HgShader& shader)
{
	//get the attribute location from the shader
	OGLShaderHandle program_id = shader.getProgramHandle();

	const auto attribLocation = glGetAttribLocation(program_id, m_attributeName.c_str());

	if (attribLocation < 0)
	{
		InvalidAttributeError(shader, m_attributeName);
		return;
	}

	//glVertexAttribPointer requires a buffer be bound
	glBindBuffer(GL_ARRAY_BUFFER, m_attributeBuffer.getValue());

	constexpr size_t stride = sizeof(float) * 16;

	for (int i = 0; i < 4; i++)
	{
		const size_t byteOffset = imd.byteOffset + (sizeof(float) * 4 * i);
		glEnableVertexAttribArray(attribLocation + i);
		glVertexAttribPointer(attribLocation + i, 4, GL_FLOAT, GL_FALSE, stride, (void*)byteOffset);
		glVertexAttribDivisor(attribLocation + i, 1); //advance per instance drawn
	}

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	setNeedSetup(false);
}<commit_msg>debug attribute location<commit_after>#include <VertexAttributeBuffer.h>

void GLVertexAttributeBuffer::toGPU(const void* data, const size_t size)
{
	if (bufferId.value == 0)
	{
		Init();
	}

	glBindBuffer(GL_ARRAY_BUFFER, bufferId.value);

	if (m_maxSize < size) {
		//grow buffer and load all data
		glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
	}
	else {
		//load all data
		glBufferSubData(GL_ARRAY_BUFFER, 0, size, data);
	}
	m_maxSize = size;

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void MatrixVertexAttribute::SendToGPU(const IHgGPUBuffer* bufferObject)
{
	m_attributeBuffer.toGPU(bufferObject->getBufferPtr(), bufferObject->sizeBytes());
}

void InvalidAttributeError(const HgShader& shader, const std::string& name)
{
	auto ss = shader.sourceStruct();
	fprintf(stderr, "Invalid Attribute: %s (shader %s)\n", name.c_str(), ss->vert_file_path.c_str());
}

void MatrixVertexAttribute::Setup(const Instancing::InstancingMetaData& imd, const HgShader& shader)
{
	//get the attribute location from the shader
	OGLShaderHandle program_id = shader.getProgramHandle();

	const auto attribLocation = glGetAttribLocation(program_id, m_attributeName.c_str());

	if (attribLocation < 0)
	{
		InvalidAttributeError(shader, m_attributeName);
		return;
	}

//	fprintf(stderr, "%s : %d\n", m_attributeName.c_str(), m_attributeBuffer.getValue());

	//glVertexAttribPointer requires a buffer be bound
	glBindBuffer(GL_ARRAY_BUFFER, m_attributeBuffer.getValue());

	constexpr size_t stride = sizeof(float) * 16;

	for (int i = 0; i < 4; i++)
	{
		const size_t byteOffset = imd.byteOffset + (sizeof(float) * 4 * i);
		const auto location = attribLocation + i;
		glEnableVertexAttribArray(location);
		glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, stride, (void*)byteOffset);
		glVertexAttribDivisor(location, 1); //advance per instance drawn
	}

	glBindBuffer(GL_ARRAY_BUFFER, 0);

	setNeedSetup(false);
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: XMLScanner.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: ihi $ $Date: 2008-02-04 13:50:23 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

/**
  Copyright 2005 Sun Microsystems, Inc.
  */

#include "XMLScanner.hxx"
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <rtftok/RTFScanner.hxx>
#include <rtftok/RTFScannerHandler.hxx>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <ucbhelper/contentbroker.hxx>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <osl/process.h>
#include <rtl/string.hxx>
#include <hash_set>
#include <assert.h>
#include <string>
#include <cppuhelper/implbase2.hxx>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <comphelper/storagehelper.hxx>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <comphelper/seqstream.hxx>

#include <ctype.h>
#include <iostream>

using namespace ::com::sun::star;
using namespace ::std;

namespace writerfilter { namespace rtftok {

const sal_Char XMLScanner::SERVICE_NAME[40] = "debugservices.rtftok.XMLScanner";
const sal_Char XMLScanner::IMPLEMENTATION_NAME[40] = "debugservices.rtftok.XMLScanner";

class XmlRtfScannerHandler : public writerfilter::rtftok::RTFScannerHandler
{
    std::vector<unsigned char> binBuffer;
    int objDataLevel;
    int numOfOLEs;
    unsigned char hb;
    int numOfOLEChars;
    uno::Reference<lang::XMultiServiceFactory> xServiceFactory;
    uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess;
    string charBuffer;
    string ucharBuffer;
    vector<string> vCloseTags;

    void xmlout(const string & str)
    {
        for (size_t n = 0; n < str.length(); ++n)
        {
            char c = str[n];

            switch (c)
            {
            case '<': cout << "<"; break;
            case '>': cout << ">"; break;
            case '&': cout << "&"; break;
            default:
                cout << c;

                break;
            }
        }
    }

    void clearBuffers()
    {
        if (charBuffer.length() > 0)
        {
            cout << "<text>";
            xmlout(charBuffer);
            cout << "</text>" << endl;
        }

        charBuffer = "";

        if (ucharBuffer.length() > 0)
        {
            cout << "<utext>";
            xmlout(ucharBuffer);
            cout << ucharBuffer << "</utext>" << endl;
        }

        ucharBuffer = "";
    }

    void dest(char* token, char* value)
    {
        clearBuffers();
        cout << "<dest name=\"" << token << "\" value=\""<< value << "\">" << endl;
        vCloseTags.push_back("</dest>");
    }
    void ctrl(char*token, char* value)
    {
        clearBuffers();
        cout << "<" << token << ">" << value << "</" << token << ">"
             << endl;
    }
    void lbrace(void)
    {
        clearBuffers();
        cout << "<brace>" << endl;
        vCloseTags.push_back("</brace>");
    }
    void rbrace(void)
    {
        clearBuffers();
        cout << vCloseTags.back() << endl;
        vCloseTags.pop_back();
    }
    void addSpaces(int count)
    {
        clearBuffers();
        cout << "<spaces count=\"" << count << "\"/>" << endl;
    }
    void addBinData(unsigned char /*data*/)
    {
        clearBuffers();
        cout << "<bindata/>" << endl;
    }
    void addChar(char ch)
    {
        charBuffer += ch;
    }
    void addCharU(sal_Unicode ch)
    {
        ucharBuffer += sal_Char(ch < 128 ? ch : '.');
    }
    void addHexChar(char* hexch)
    {
        clearBuffers();
        cout << "<hexchar value=\"" << hexch << "\"/>" << endl;
    }

public:
    XmlRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> &xServiceFactory_, uno::Reference<com::sun::star::ucb::XSimpleFileAccess> &xFileAccess_) :
    objDataLevel(0), numOfOLEs(0),
    xServiceFactory(xServiceFactory_),
    xFileAccess(xFileAccess_)
    {
    }

    virtual ~XmlRtfScannerHandler() {}

    void dump()
    {
    }
};

class RtfInputSourceImpl : public rtftok::RTFInputSource
{
private:
    uno::Reference< io::XInputStream > xInputStream;
    uno::Reference< io::XSeekable > xSeekable;
    uno::Reference< task::XStatusIndicator > xStatusIndicator;
    sal_Int64 bytesTotal;
    sal_Int64 bytesRead;
public:
    RtfInputSourceImpl(uno::Reference< io::XInputStream > &xInputStream_, uno::Reference< task::XStatusIndicator > &xStatusIndicator_) :
      xInputStream(xInputStream_),
      xStatusIndicator(xStatusIndicator_),
      bytesRead(0)
    {
        xSeekable=uno::Reference< io::XSeekable >(xInputStream, uno::UNO_QUERY);
        if (xSeekable.is())
            bytesTotal=xSeekable->getLength();
        if (xStatusIndicator.is() && xSeekable.is())
        {
            xStatusIndicator->start(::rtl::OUString::createFromAscii("Converting"), 100);
        }
    }

    virtual ~RtfInputSourceImpl() {}

    int read(void *buf, int maxlen)
    {
        uno::Sequence< sal_Int8 > buffer;
        int len=xInputStream->readSomeBytes(buffer,maxlen);
        if (len>0)
        {
            sal_Int8 *_buffer=buffer.getArray();
            memcpy(buf, _buffer, len);
            bytesRead+=len;
            if (xStatusIndicator.is())
            {
                if (xSeekable.is())
                {
                    xStatusIndicator->setValue((int)(bytesRead*100/bytesTotal));
                }
                else
                {
                    char buf1[100];
                    sprintf(buf1, "Converted %" SAL_PRIdINT64 " KB", bytesRead/1024);
                    xStatusIndicator->start(::rtl::OUString::createFromAscii(buf1), 0);
                }
            }
            return len;
        }
        else
        {
            if (xStatusIndicator.is())
            {
                xStatusIndicator->end();
            }
            return 0;
        }
    }
};

XMLScanner::XMLScanner(const uno::Reference< uno::XComponentContext > &xContext_) :
xContext( xContext_ )
{
}

sal_Int32 SAL_CALL XMLScanner::run( const uno::Sequence< rtl::OUString >& aArguments ) throw (uno::RuntimeException)
{
      uno::Sequence<uno::Any> aUcbInitSequence(2);
    aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
    aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
    uno::Reference<lang::XMultiServiceFactory> xServiceFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW);
    uno::Reference<lang::XMultiComponentFactory> xFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW );
    if (::ucbhelper::ContentBroker::initialize(xServiceFactory, aUcbInitSequence))
    {
            rtl::OUString arg=aArguments[0];

            uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess(
            xFactory->createInstanceWithContext(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")),
                xContext), uno::UNO_QUERY_THROW );

            rtl_uString *dir=NULL;
            osl_getProcessWorkingDir(&dir);
            rtl::OUString absFileUrl;
            osl_getAbsoluteFileURL(dir, arg.pData, &absFileUrl.pData);
            rtl_uString_release(dir);

            uno::Reference <lang::XSingleServiceFactory> xStorageFactory(
                xServiceFactory->createInstance (rtl::OUString::createFromAscii("com.sun.star.embed.StorageFactory")), uno::UNO_QUERY_THROW);

#if 0
            rtl::OUString outFileUrl;
            {
            rtl_uString *dir1=NULL;
            osl_getProcessWorkingDir(&dir1);
            osl_getAbsoluteFileURL(dir1, aArguments[1].pData, &outFileUrl.pData);
            rtl_uString_release(dir1);
            }

            uno::Sequence< uno::Any > aArgs( 2 );
            aArgs[0] <<= outFileUrl;
            aArgs[1] <<= embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE;
            uno::Reference<embed::XStorage> xStorage(xStorageFactory->createInstanceWithArguments(aArgs), uno::UNO_QUERY_THROW);
            uno::Reference<beans::XPropertySet> xPropSet(xStorage, uno::UNO_QUERY_THROW);
            xPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.oasis.opendocument.text")));
#endif
            uno::Reference<io::XInputStream> xInputStream = xFileAccess->openFileRead(absFileUrl);
            uno::Reference< task::XStatusIndicator > xStatusIndicator;

            RtfInputSourceImpl rtfInputSource(xInputStream, xStatusIndicator);
            XmlRtfScannerHandler eventHandler(xServiceFactory, xFileAccess);
            writerfilter::rtftok::RTFScanner *rtfScanner=writerfilter::rtftok::RTFScanner::createRTFScanner(rtfInputSource, eventHandler);

            cout << "<out>" << endl;
            rtfScanner->yylex();
            cout << "</out>" << endl;
            delete rtfScanner;

        ::ucbhelper::ContentBroker::deinitialize();
    }
    else
    {
        fprintf(stderr, "can't initialize UCB");
    }
    return 0;
}

::rtl::OUString XMLScanner_getImplementationName ()
{
    return rtl::OUString::createFromAscii ( XMLScanner::IMPLEMENTATION_NAME );
}

sal_Bool SAL_CALL XMLScanner_supportsService( const ::rtl::OUString& ServiceName )
{
    return ServiceName.equals( rtl::OUString::createFromAscii( XMLScanner::SERVICE_NAME ) );
}
uno::Sequence< rtl::OUString > SAL_CALL XMLScanner_getSupportedServiceNames(  ) throw (uno::RuntimeException)
{
    uno::Sequence < rtl::OUString > aRet(1);
    rtl::OUString* pArray = aRet.getArray();
    pArray[0] =  rtl::OUString::createFromAscii ( XMLScanner::SERVICE_NAME );
    return aRet;
}

uno::Reference< uno::XInterface > SAL_CALL XMLScanner_createInstance( const uno::Reference< uno::XComponentContext > & xContext) throw( uno::Exception )
{
    return (cppu::OWeakObject*) new XMLScanner( xContext );
}

} } /* end namespace writerfilter::rtftok */
<commit_msg>INTEGRATION: CWS changefileheader (1.8.10); FILE MERGED 2008/03/28 15:53:08 rt 1.8.10.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: XMLScanner.cxx,v $
 * $Revision: 1.9 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

/**
  Copyright 2005 Sun Microsystems, Inc.
  */

#include "XMLScanner.hxx"
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <rtftok/RTFScanner.hxx>
#include <rtftok/RTFScannerHandler.hxx>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <ucbhelper/contentbroker.hxx>
#include <com/sun/star/ucb/XSimpleFileAccess.hpp>
#include <osl/process.h>
#include <rtl/string.hxx>
#include <hash_set>
#include <assert.h>
#include <string>
#include <cppuhelper/implbase2.hxx>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/embed/XStorage.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <comphelper/storagehelper.hxx>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <comphelper/seqstream.hxx>

#include <ctype.h>
#include <iostream>

using namespace ::com::sun::star;
using namespace ::std;

namespace writerfilter { namespace rtftok {

const sal_Char XMLScanner::SERVICE_NAME[40] = "debugservices.rtftok.XMLScanner";
const sal_Char XMLScanner::IMPLEMENTATION_NAME[40] = "debugservices.rtftok.XMLScanner";

class XmlRtfScannerHandler : public writerfilter::rtftok::RTFScannerHandler
{
    std::vector<unsigned char> binBuffer;
    int objDataLevel;
    int numOfOLEs;
    unsigned char hb;
    int numOfOLEChars;
    uno::Reference<lang::XMultiServiceFactory> xServiceFactory;
    uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess;
    string charBuffer;
    string ucharBuffer;
    vector<string> vCloseTags;

    void xmlout(const string & str)
    {
        for (size_t n = 0; n < str.length(); ++n)
        {
            char c = str[n];

            switch (c)
            {
            case '<': cout << "<"; break;
            case '>': cout << ">"; break;
            case '&': cout << "&"; break;
            default:
                cout << c;

                break;
            }
        }
    }

    void clearBuffers()
    {
        if (charBuffer.length() > 0)
        {
            cout << "<text>";
            xmlout(charBuffer);
            cout << "</text>" << endl;
        }

        charBuffer = "";

        if (ucharBuffer.length() > 0)
        {
            cout << "<utext>";
            xmlout(ucharBuffer);
            cout << ucharBuffer << "</utext>" << endl;
        }

        ucharBuffer = "";
    }

    void dest(char* token, char* value)
    {
        clearBuffers();
        cout << "<dest name=\"" << token << "\" value=\""<< value << "\">" << endl;
        vCloseTags.push_back("</dest>");
    }
    void ctrl(char*token, char* value)
    {
        clearBuffers();
        cout << "<" << token << ">" << value << "</" << token << ">"
             << endl;
    }
    void lbrace(void)
    {
        clearBuffers();
        cout << "<brace>" << endl;
        vCloseTags.push_back("</brace>");
    }
    void rbrace(void)
    {
        clearBuffers();
        cout << vCloseTags.back() << endl;
        vCloseTags.pop_back();
    }
    void addSpaces(int count)
    {
        clearBuffers();
        cout << "<spaces count=\"" << count << "\"/>" << endl;
    }
    void addBinData(unsigned char /*data*/)
    {
        clearBuffers();
        cout << "<bindata/>" << endl;
    }
    void addChar(char ch)
    {
        charBuffer += ch;
    }
    void addCharU(sal_Unicode ch)
    {
        ucharBuffer += sal_Char(ch < 128 ? ch : '.');
    }
    void addHexChar(char* hexch)
    {
        clearBuffers();
        cout << "<hexchar value=\"" << hexch << "\"/>" << endl;
    }

public:
    XmlRtfScannerHandler(uno::Reference<lang::XMultiServiceFactory> &xServiceFactory_, uno::Reference<com::sun::star::ucb::XSimpleFileAccess> &xFileAccess_) :
    objDataLevel(0), numOfOLEs(0),
    xServiceFactory(xServiceFactory_),
    xFileAccess(xFileAccess_)
    {
    }

    virtual ~XmlRtfScannerHandler() {}

    void dump()
    {
    }
};

class RtfInputSourceImpl : public rtftok::RTFInputSource
{
private:
    uno::Reference< io::XInputStream > xInputStream;
    uno::Reference< io::XSeekable > xSeekable;
    uno::Reference< task::XStatusIndicator > xStatusIndicator;
    sal_Int64 bytesTotal;
    sal_Int64 bytesRead;
public:
    RtfInputSourceImpl(uno::Reference< io::XInputStream > &xInputStream_, uno::Reference< task::XStatusIndicator > &xStatusIndicator_) :
      xInputStream(xInputStream_),
      xStatusIndicator(xStatusIndicator_),
      bytesRead(0)
    {
        xSeekable=uno::Reference< io::XSeekable >(xInputStream, uno::UNO_QUERY);
        if (xSeekable.is())
            bytesTotal=xSeekable->getLength();
        if (xStatusIndicator.is() && xSeekable.is())
        {
            xStatusIndicator->start(::rtl::OUString::createFromAscii("Converting"), 100);
        }
    }

    virtual ~RtfInputSourceImpl() {}

    int read(void *buf, int maxlen)
    {
        uno::Sequence< sal_Int8 > buffer;
        int len=xInputStream->readSomeBytes(buffer,maxlen);
        if (len>0)
        {
            sal_Int8 *_buffer=buffer.getArray();
            memcpy(buf, _buffer, len);
            bytesRead+=len;
            if (xStatusIndicator.is())
            {
                if (xSeekable.is())
                {
                    xStatusIndicator->setValue((int)(bytesRead*100/bytesTotal));
                }
                else
                {
                    char buf1[100];
                    sprintf(buf1, "Converted %" SAL_PRIdINT64 " KB", bytesRead/1024);
                    xStatusIndicator->start(::rtl::OUString::createFromAscii(buf1), 0);
                }
            }
            return len;
        }
        else
        {
            if (xStatusIndicator.is())
            {
                xStatusIndicator->end();
            }
            return 0;
        }
    }
};

XMLScanner::XMLScanner(const uno::Reference< uno::XComponentContext > &xContext_) :
xContext( xContext_ )
{
}

sal_Int32 SAL_CALL XMLScanner::run( const uno::Sequence< rtl::OUString >& aArguments ) throw (uno::RuntimeException)
{
      uno::Sequence<uno::Any> aUcbInitSequence(2);
    aUcbInitSequence[0] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Local"));
    aUcbInitSequence[1] <<= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Office"));
    uno::Reference<lang::XMultiServiceFactory> xServiceFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW);
    uno::Reference<lang::XMultiComponentFactory> xFactory(xContext->getServiceManager(), uno::UNO_QUERY_THROW );
    if (::ucbhelper::ContentBroker::initialize(xServiceFactory, aUcbInitSequence))
    {
            rtl::OUString arg=aArguments[0];

            uno::Reference<com::sun::star::ucb::XSimpleFileAccess> xFileAccess(
            xFactory->createInstanceWithContext(
                ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SimpleFileAccess")),
                xContext), uno::UNO_QUERY_THROW );

            rtl_uString *dir=NULL;
            osl_getProcessWorkingDir(&dir);
            rtl::OUString absFileUrl;
            osl_getAbsoluteFileURL(dir, arg.pData, &absFileUrl.pData);
            rtl_uString_release(dir);

            uno::Reference <lang::XSingleServiceFactory> xStorageFactory(
                xServiceFactory->createInstance (rtl::OUString::createFromAscii("com.sun.star.embed.StorageFactory")), uno::UNO_QUERY_THROW);

#if 0
            rtl::OUString outFileUrl;
            {
            rtl_uString *dir1=NULL;
            osl_getProcessWorkingDir(&dir1);
            osl_getAbsoluteFileURL(dir1, aArguments[1].pData, &outFileUrl.pData);
            rtl_uString_release(dir1);
            }

            uno::Sequence< uno::Any > aArgs( 2 );
            aArgs[0] <<= outFileUrl;
            aArgs[1] <<= embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE;
            uno::Reference<embed::XStorage> xStorage(xStorageFactory->createInstanceWithArguments(aArgs), uno::UNO_QUERY_THROW);
            uno::Reference<beans::XPropertySet> xPropSet(xStorage, uno::UNO_QUERY_THROW);
            xPropSet->setPropertyValue(rtl::OUString::createFromAscii("MediaType"), uno::makeAny(rtl::OUString::createFromAscii("application/vnd.oasis.opendocument.text")));
#endif
            uno::Reference<io::XInputStream> xInputStream = xFileAccess->openFileRead(absFileUrl);
            uno::Reference< task::XStatusIndicator > xStatusIndicator;

            RtfInputSourceImpl rtfInputSource(xInputStream, xStatusIndicator);
            XmlRtfScannerHandler eventHandler(xServiceFactory, xFileAccess);
            writerfilter::rtftok::RTFScanner *rtfScanner=writerfilter::rtftok::RTFScanner::createRTFScanner(rtfInputSource, eventHandler);

            cout << "<out>" << endl;
            rtfScanner->yylex();
            cout << "</out>" << endl;
            delete rtfScanner;

        ::ucbhelper::ContentBroker::deinitialize();
    }
    else
    {
        fprintf(stderr, "can't initialize UCB");
    }
    return 0;
}

::rtl::OUString XMLScanner_getImplementationName ()
{
    return rtl::OUString::createFromAscii ( XMLScanner::IMPLEMENTATION_NAME );
}

sal_Bool SAL_CALL XMLScanner_supportsService( const ::rtl::OUString& ServiceName )
{
    return ServiceName.equals( rtl::OUString::createFromAscii( XMLScanner::SERVICE_NAME ) );
}
uno::Sequence< rtl::OUString > SAL_CALL XMLScanner_getSupportedServiceNames(  ) throw (uno::RuntimeException)
{
    uno::Sequence < rtl::OUString > aRet(1);
    rtl::OUString* pArray = aRet.getArray();
    pArray[0] =  rtl::OUString::createFromAscii ( XMLScanner::SERVICE_NAME );
    return aRet;
}

uno::Reference< uno::XInterface > SAL_CALL XMLScanner_createInstance( const uno::Reference< uno::XComponentContext > & xContext) throw( uno::Exception )
{
    return (cppu::OWeakObject*) new XMLScanner( xContext );
}

} } /* end namespace writerfilter::rtftok */
<|endoftext|>