<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- standard modules used ----------------------------------------------------
#include "Anything.h"
#include "Threads.h"
#include "TestThread.h"
#include "Dbg.h"

//--- test modules used --------------------------------------------------------
#include "TestSuite.h"

//--- module under test --------------------------------------------------------
#include "ThreadPools.h"

//--- interface include --------------------------------------------------------
#include "WorkerPoolManagerTest.h"

//---- WorkerPoolManagerTest ----------------------------------------------------------------
WorkerPoolManagerTest::WorkerPoolManagerTest(TString tname) : TestCase(tname), fCheckMutex("WorkerPoolManager")
{
	StartTrace(WorkerPoolManagerTest.Ctor);
}

WorkerPoolManagerTest::~WorkerPoolManagerTest()
{
	StartTrace(WorkerPoolManagerTest.Dtor);
}

// builds up a suite of testcases, add a line for each testmethod
Test *WorkerPoolManagerTest::suite ()
{
	StartTrace(WorkerPoolManagerTest.suite);
	TestSuite *testSuite = new TestSuite;

	testSuite->addTest (NEW_CASE(WorkerPoolManagerTest, InitTest));
	testSuite->addTest (NEW_CASE(WorkerPoolManagerTest, EnterLeaveTests));

	return testSuite;

} // suite

// setup for this TestCase
void WorkerPoolManagerTest::setUp ()
{
	StartTrace(WorkerPoolManagerTest.setUp);
} // setUp

void WorkerPoolManagerTest::tearDown ()
{
	StartTrace(WorkerPoolManagerTest.tearDown);
} // tearDown

void WorkerPoolManagerTest::InitTest()
{
	StartTrace(WorkerPoolManagerTest.InitTest);
	SamplePoolManager wpm("InitTestPool");

	Anything config;
	config["timeout"] = 1;
	config["test"] = Anything((IFAObject *)this);
	t_assert(wpm.Init(0, 0, 0, 0, ROAnything(config)) == 0);	// always allocate at least one worker
	t_assert(wpm.MaxRequests2Run() == 1);
	t_assert(wpm.NumOfRequestsRunning() == 0);
	t_assert(wpm.Init(-1, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == 1);
	t_assert(wpm.NumOfRequestsRunning() == 0);
	t_assert(wpm.Init(1, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == 1);
	t_assert(wpm.NumOfRequestsRunning() == 0);
	t_assert(wpm.Init(10, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == 10);
	t_assert(wpm.NumOfRequestsRunning() == 0);

	for (long i = 0; i < 10; i++) {
		t_assertm(wpm.DoGetWorker(i) != 0, "expected 10 Workers to be there");
	}
}

void WorkerPoolManagerTest::EnterLeaveTests()
{
	StartTrace(WorkerPoolManagerTest.InitTest);
	const long cPoolSz = 2;
	SamplePoolManager wpm("EnterLeaveTestsPool");
	Anything config;
	config["timeout"] = 1;
	config["test"] = Anything((IFAObject *)this);
	t_assert(wpm.Init(cPoolSz, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == cPoolSz);
	t_assert(wpm.NumOfRequestsRunning() == 0);

	Anything work;
	for (long i = 0; i < 2 * cPoolSz; i++) {
		wpm.Enter(ROAnything(work));
	}
	t_assert(wpm.AwaitEmpty(5));
	t_assert(wpm.Terminate());

	Anything expected;
	Anything statistic;
	wpm.Statistic(statistic);
	expected["PoolSize"] = 2;
	expected["CurrentParallelRequests"] = 0;
	expected["MaxParallelRequests"] = 2;
	expected["TotalRequests"] = 4;
	statistic.Remove("TotalTime"); // since varies
	statistic.Remove("AverageTime"); // since varies
	statistic.Remove("TRX/sec"); // since varies

	assertAnyEqualm(expected, statistic, "statistic differs");

}

void WorkerPoolManagerTest::CheckPrepare2Run(bool isReady, bool wasPrepared)
{
	MutexEntry me(fCheckMutex);
	me.Use();
	t_assertm(isReady, "Worker must be in ready state");
	t_assertm(!wasPrepared, "Worker must not be prepared");
}

void WorkerPoolManagerTest::CheckProcessWorkload(bool isWorking, bool wasPrepared)
{
	MutexEntry me(fCheckMutex);
	me.Use();
	t_assertm(isWorking, "Worker must be in working state");
	t_assertm(wasPrepared, "Worker must have been prepared");
}
<commit_msg>changed macros<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- standard modules used ----------------------------------------------------
#include "Anything.h"
#include "Threads.h"
#include "TestThread.h"
#include "Dbg.h"

//--- test modules used --------------------------------------------------------
#include "TestSuite.h"

//--- module under test --------------------------------------------------------
#include "ThreadPools.h"

//--- interface include --------------------------------------------------------
#include "WorkerPoolManagerTest.h"

//---- WorkerPoolManagerTest ----------------------------------------------------------------
WorkerPoolManagerTest::WorkerPoolManagerTest(TString tname) : TestCase(tname), fCheckMutex("WorkerPoolManager")
{
	StartTrace(WorkerPoolManagerTest.Ctor);
}

WorkerPoolManagerTest::~WorkerPoolManagerTest()
{
	StartTrace(WorkerPoolManagerTest.Dtor);
}

// builds up a suite of testcases, add a line for each testmethod
Test *WorkerPoolManagerTest::suite ()
{
	StartTrace(WorkerPoolManagerTest.suite);
	TestSuite *testSuite = new TestSuite;

	ADD_CASE(testSuite, WorkerPoolManagerTest, InitTest);
	ADD_CASE(testSuite, WorkerPoolManagerTest, EnterLeaveTests);

	return testSuite;
}

// setup for this TestCase
void WorkerPoolManagerTest::setUp ()
{
	StartTrace(WorkerPoolManagerTest.setUp);
} // setUp

void WorkerPoolManagerTest::tearDown ()
{
	StartTrace(WorkerPoolManagerTest.tearDown);
} // tearDown

void WorkerPoolManagerTest::InitTest()
{
	StartTrace(WorkerPoolManagerTest.InitTest);
	SamplePoolManager wpm("InitTestPool");

	Anything config;
	config["timeout"] = 1;
	config["test"] = Anything((IFAObject *)this);
	t_assert(wpm.Init(0, 0, 0, 0, ROAnything(config)) == 0);	// always allocate at least one worker
	t_assert(wpm.MaxRequests2Run() == 1);
	t_assert(wpm.NumOfRequestsRunning() == 0);
	t_assert(wpm.Init(-1, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == 1);
	t_assert(wpm.NumOfRequestsRunning() == 0);
	t_assert(wpm.Init(1, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == 1);
	t_assert(wpm.NumOfRequestsRunning() == 0);
	t_assert(wpm.Init(10, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == 10);
	t_assert(wpm.NumOfRequestsRunning() == 0);

	for (long i = 0; i < 10; i++) {
		t_assertm(wpm.DoGetWorker(i) != 0, "expected 10 Workers to be there");
	}
}

void WorkerPoolManagerTest::EnterLeaveTests()
{
	StartTrace(WorkerPoolManagerTest.EnterLeaveTests);
	const long cPoolSz = 2;
	SamplePoolManager wpm("EnterLeaveTestsPool");
	Anything config;
	config["timeout"] = 1;
	config["test"] = Anything((IFAObject *)this);
	t_assert(wpm.Init(cPoolSz, 0, 0, 0, ROAnything(config)) == 0);
	t_assert(wpm.MaxRequests2Run() == cPoolSz);
	t_assert(wpm.NumOfRequestsRunning() == 0);

	Anything work;
	for (long i = 0; i < 2 * cPoolSz; i++) {
		wpm.Enter(ROAnything(work));
	}
	t_assert(wpm.AwaitEmpty(5));
	t_assert(wpm.Terminate());

	Anything expected;
	Anything statistic;
	wpm.Statistic(statistic);
	expected["PoolSize"] = 2;
	expected["CurrentParallelRequests"] = 0;
	expected["MaxParallelRequests"] = 2;
	expected["TotalRequests"] = 4;
	statistic.Remove("TotalTime"); // since varies
	statistic.Remove("AverageTime"); // since varies
	statistic.Remove("TRX/sec"); // since varies

	assertAnyEqualm(expected, statistic, "statistic differs");
}

void WorkerPoolManagerTest::CheckPrepare2Run(bool isReady, bool wasPrepared)
{
	MutexEntry me(fCheckMutex);
	me.Use();
	t_assertm(isReady, "Worker must be in ready state");
	t_assertm(!wasPrepared, "Worker must not be prepared");
}

void WorkerPoolManagerTest::CheckProcessWorkload(bool isWorking, bool wasPrepared)
{
	MutexEntry me(fCheckMutex);
	me.Use();
	t_assertm(isWorking, "Worker must be in working state");
	t_assertm(wasPrepared, "Worker must have been prepared");
}
<|endoftext|>


<commit_before>#include "../../testing/testing.hpp"

#include "../platform.hpp"

#include "../../defines.hpp"

#include "../../coding/file_writer.hpp"
#include "../../coding/internal/file_data.hpp"

#include "../../base/logging.hpp"

char const * TEST_FILE_NAME = "some_temporary_unit_test_file.tmp";

UNIT_TEST(WritableDir)
{
  string const path = GetPlatform().WritableDir() + TEST_FILE_NAME;

  try
  {
    my::FileData f(path, my::FileData::OP_WRITE_TRUNCATE);
  }
  catch (Writer::OpenException const &)
  {
    LOG(LCRITICAL, ("Can't create file"));
    return;
  }

  my::DeleteFileX(path);
}

UNIT_TEST(WritablePathForFile)
{
  Platform & pl = GetPlatform();
  string const p1 = pl.WritableDir() + TEST_FILE_NAME;
  string const p2 = pl.WritablePathForFile(TEST_FILE_NAME);
  TEST_EQUAL(p1, p2, ());
}

UNIT_TEST(GetReader)
{
  char const * NON_EXISTING_FILE = "mgbwuerhsnmbui45efhdbn34.tmp";
  char const * arr[] = { "drules_proto.txt", "basic_ldpi.skn", "classificator.txt", "minsk-pass.mwm" };
  Platform & p = GetPlatform();
  for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
  {
    ReaderPtr<Reader> r = p.GetReader(arr[i]);
    TEST_GREATER(r.Size(), 0, ("File should exist!"));
  }

  bool wasException = false;
  try
  {
    ReaderPtr<Reader> r = p.GetReader(NON_EXISTING_FILE);
  }
  catch (FileAbsentException const &)
  {
    wasException = true;
  }
  TEST_EQUAL(wasException, true, ());
}

UNIT_TEST(GetFilesInDir)
{
  Platform & pl = GetPlatform();
  Platform::FilesList files;

  pl.GetFilesInDir(pl.WritableDir(), "*" DATA_FILE_EXTENSION, files);
  TEST_GREATER(files.size(), 0, ("/data/ folder should contain some data files"));

  files.clear();

  pl.GetFilesInDir(pl.WritableDir(), "asdnonexistentfile.dsa", files);
  TEST_EQUAL(files.size(), 0, ());
}

UNIT_TEST(GetFileSize)
{
  Platform & pl = GetPlatform();
  uint64_t size = 123141;
  TEST(!pl.GetFileSizeByName("adsmngfuwrbfyfwe", size), ());
  TEST(!Platform::GetFileSizeByFullPath("adsmngfuwrbfyfwe", size), ());

  {
    FileWriter testFile(TEST_FILE_NAME);
    testFile.Write("HOHOHO", 6);
  }
  size = 0;
  TEST(Platform::GetFileSizeByFullPath(TEST_FILE_NAME, size), ());
  TEST_EQUAL(size, 6, ());

  FileWriter::DeleteFileX(TEST_FILE_NAME);

  {
    FileWriter testFile(pl.WritablePathForFile(TEST_FILE_NAME));
    testFile.Write("HOHOHO", 6);
  }
  size = 0;
  TEST(pl.GetFileSizeByName(TEST_FILE_NAME, size), ());
  TEST_EQUAL(size, 6, ());

  FileWriter::DeleteFileX(pl.WritablePathForFile(TEST_FILE_NAME));
}

UNIT_TEST(CpuCores)
{
  int const coresNum = GetPlatform().CpuCores();
  TEST_GREATER(coresNum, 0, ());
  TEST_LESS_OR_EQUAL(coresNum, 128, ());
}

UNIT_TEST(GetWritableStorageStatus)
{
  TEST_EQUAL(Platform::STORAGE_OK, GetPlatform().GetWritableStorageStatus(100000), ());
  TEST_EQUAL(Platform::NOT_ENOUGH_SPACE, GetPlatform().GetWritableStorageStatus(0xFFFFFFFFUL), ());
}
<commit_msg>Fix platform_test.<commit_after>#include "../../testing/testing.hpp"

#include "../platform.hpp"

#include "../../defines.hpp"

#include "../../coding/file_writer.hpp"
#include "../../coding/internal/file_data.hpp"

#include "../../base/logging.hpp"

char const * TEST_FILE_NAME = "some_temporary_unit_test_file.tmp";

UNIT_TEST(WritableDir)
{
  string const path = GetPlatform().WritableDir() + TEST_FILE_NAME;

  try
  {
    my::FileData f(path, my::FileData::OP_WRITE_TRUNCATE);
  }
  catch (Writer::OpenException const &)
  {
    LOG(LCRITICAL, ("Can't create file"));
    return;
  }

  my::DeleteFileX(path);
}

UNIT_TEST(WritablePathForFile)
{
  Platform & pl = GetPlatform();
  string const p1 = pl.WritableDir() + TEST_FILE_NAME;
  string const p2 = pl.WritablePathForFile(TEST_FILE_NAME);
  TEST_EQUAL(p1, p2, ());
}

UNIT_TEST(GetReader)
{
  char const * NON_EXISTING_FILE = "mgbwuerhsnmbui45efhdbn34.tmp";
  char const * arr[] = { "drules_proto.txt", "basic_ldpi.skn", "classificator.txt", "minsk-pass.mwm" };
  Platform & p = GetPlatform();
  for (size_t i = 0; i < ARRAY_SIZE(arr); ++i)
  {
    ReaderPtr<Reader> r = p.GetReader(arr[i]);
    TEST_GREATER(r.Size(), 0, ("File should exist!"));
  }

  bool wasException = false;
  try
  {
    ReaderPtr<Reader> r = p.GetReader(NON_EXISTING_FILE);
  }
  catch (FileAbsentException const &)
  {
    wasException = true;
  }
  TEST_EQUAL(wasException, true, ());
}

UNIT_TEST(GetFilesInDir)
{
  Platform & pl = GetPlatform();
  Platform::FilesList files;

  pl.GetFilesInDir(pl.WritableDir(), "*" DATA_FILE_EXTENSION, files);
  TEST_GREATER(files.size(), 0, ("/data/ folder should contain some data files"));

  files.clear();

  pl.GetFilesInDir(pl.WritableDir(), "asdnonexistentfile.dsa", files);
  TEST_EQUAL(files.size(), 0, ());
}

UNIT_TEST(GetFileSize)
{
  Platform & pl = GetPlatform();
  uint64_t size = 123141;
  TEST(!pl.GetFileSizeByName("adsmngfuwrbfyfwe", size), ());
  TEST(!Platform::GetFileSizeByFullPath("adsmngfuwrbfyfwe", size), ());

  {
    FileWriter testFile(TEST_FILE_NAME);
    testFile.Write("HOHOHO", 6);
  }
  size = 0;
  TEST(Platform::GetFileSizeByFullPath(TEST_FILE_NAME, size), ());
  TEST_EQUAL(size, 6, ());

  FileWriter::DeleteFileX(TEST_FILE_NAME);

  {
    FileWriter testFile(pl.WritablePathForFile(TEST_FILE_NAME));
    testFile.Write("HOHOHO", 6);
  }
  size = 0;
  TEST(pl.GetFileSizeByName(TEST_FILE_NAME, size), ());
  TEST_EQUAL(size, 6, ());

  FileWriter::DeleteFileX(pl.WritablePathForFile(TEST_FILE_NAME));
}

UNIT_TEST(CpuCores)
{
  int const coresNum = GetPlatform().CpuCores();
  TEST_GREATER(coresNum, 0, ());
  TEST_LESS_OR_EQUAL(coresNum, 128, ());
}

UNIT_TEST(GetWritableStorageStatus)
{
  TEST_EQUAL(Platform::STORAGE_OK, GetPlatform().GetWritableStorageStatus(100000), ());
  TEST_EQUAL(Platform::NOT_ENOUGH_SPACE, GetPlatform().GetWritableStorageStatus(uint64_t(-1)), ());
}
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// 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 "parallel_for_for_prefix_sum.h"
#include "../sys/regression.h"

namespace embree
{
  struct parallel_for_for_prefix_sum_regression_test : public RegressionTest
  {
    parallel_for_for_prefix_sum_regression_test(const char* name) : RegressionTest(name) {
      registerRegressionTest(this);
    }

    bool run ()
    {
      bool passed = true;

      /* create vector with random numbers */
      const size_t M = 10;
      std::vector<atomic<size_t>> flattened;
      typedef std::vector<std::vector<size_t>* > ArrayArray;
      ArrayArray array2(M);
      size_t K = 0;
      for (size_t i=0; i<M; i++) {
        const size_t N = rand() % 10;
        K += N;
        array2[i] = new std::vector<size_t>(N);
        for (size_t j=0; j<N; j++)
          (*array2[i])[j] = rand() % 10;
      }

      /* array to test global index */
      std::vector<atomic<size_t>> verify_k(K);
      for (size_t i=0; i<K; i++) verify_k[i].store(0);

      ParallelForForPrefixSumState<size_t> state(array2,size_t(1));

      /* dry run only counts */
      size_t S = parallel_for_for_prefix_sum( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
      {
        size_t s = 0;
	for (size_t i=r.begin(); i<r.end(); i++) {
          s += (*v)[i];
          verify_k[k++]++;
        }
        return s;
      }, [](size_t v0, size_t v1) { return v0+v1; });

      /* create properly sized output array */
      flattened.resize(S);
      memset(flattened.data(),0,sizeof(atomic<size_t>)*S);

      /* now we actually fill the flattened array */
      parallel_for_for_prefix_sum( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
      {
        size_t s = 0;
	for (size_t i=r.begin(); i<r.end(); i++) {
          for (size_t j=0; j<(*v)[i]; j++) {
            flattened[base+s+j]++;
          }
          s += (*v)[i];
          verify_k[k++]++;
        }
        return s;
      }, [](size_t v0, size_t v1) { return v0+v1; });

      /* check global index */
      for (size_t i=0; i<K; i++)
        passed &= (verify_k[i] == 2);

      /* check if each element was assigned exactly once */
      for (size_t i=0; i<flattened.size(); i++)
        passed &= (flattened[i] == 1);

      /* delete arrays again */
      for (size_t i=0; i<array2.size(); i++)
	delete array2[i];

      return passed;
    }
  };

  parallel_for_for_prefix_sum_regression_test parallel_for_for_prefix_sum_regression("parallel_for_for_prefix_sum_regression_test");
}
<commit_msg>not using memset in parallel_for_for_prefix_sum anymore<commit_after>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// 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 "parallel_for_for_prefix_sum.h"
#include "../sys/regression.h"

namespace embree
{
  struct parallel_for_for_prefix_sum_regression_test : public RegressionTest
  {
    parallel_for_for_prefix_sum_regression_test(const char* name) : RegressionTest(name) {
      registerRegressionTest(this);
    }

    bool run ()
    {
      bool passed = true;

      /* create vector with random numbers */
      const size_t M = 10;
      std::vector<atomic<size_t>> flattened;
      typedef std::vector<std::vector<size_t>* > ArrayArray;
      ArrayArray array2(M);
      size_t K = 0;
      for (size_t i=0; i<M; i++) {
        const size_t N = rand() % 10;
        K += N;
        array2[i] = new std::vector<size_t>(N);
        for (size_t j=0; j<N; j++)
          (*array2[i])[j] = rand() % 10;
      }

      /* array to test global index */
      std::vector<atomic<size_t>> verify_k(K);
      for (size_t i=0; i<K; i++) verify_k[i].store(0);

      ParallelForForPrefixSumState<size_t> state(array2,size_t(1));

      /* dry run only counts */
      size_t S = parallel_for_for_prefix_sum( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
      {
        size_t s = 0;
	for (size_t i=r.begin(); i<r.end(); i++) {
          s += (*v)[i];
          verify_k[k++]++;
        }
        return s;
      }, [](size_t v0, size_t v1) { return v0+v1; });

      /* create properly sized output array */
      flattened.resize(S);
      for (auto& a : flattened) a.store(0);

      /* now we actually fill the flattened array */
      parallel_for_for_prefix_sum( state, array2, size_t(0), [&](std::vector<size_t>* v, const range<size_t>& r, size_t k, const size_t base) -> size_t
      {
        size_t s = 0;
	for (size_t i=r.begin(); i<r.end(); i++) {
          for (size_t j=0; j<(*v)[i]; j++) {
            flattened[base+s+j]++;
          }
          s += (*v)[i];
          verify_k[k++]++;
        }
        return s;
      }, [](size_t v0, size_t v1) { return v0+v1; });

      /* check global index */
      for (size_t i=0; i<K; i++)
        passed &= (verify_k[i] == 2);

      /* check if each element was assigned exactly once */
      for (size_t i=0; i<flattened.size(); i++)
        passed &= (flattened[i] == 1);

      /* delete arrays again */
      for (size_t i=0; i<array2.size(); i++)
	delete array2[i];

      return passed;
    }
  };

  parallel_for_for_prefix_sum_regression_test parallel_for_for_prefix_sum_regression("parallel_for_for_prefix_sum_regression_test");
}
<|endoftext|>


<commit_before>#include "pch.h"

#include "Game.h"
#include "Event.h"

#include "Events\LoginErrorEvent.h"
#include "Events\LoginSuccessEvent.h"
#include "Events\ScreenChangedEvent.h"
#include "Events\PointerPressedEvent.h"

#include "Systems\NetworkSystem.h"

#include "Util\StringUtils.h"

#include "PinnedDownNet.h"

using namespace concurrency;

using namespace PinnedDownCore;
using namespace PinnedDownClient::Events;
using namespace PinnedDownClient::Systems;

using namespace Windows::Networking;
using namespace Windows::Networking::Sockets;

using namespace Windows::Storage::Streams;

#define PINNED_DOWN_SERVER_HOST "localhost"
#define PINNED_DOWN_SERVER_PORT "27015"
//#define REQUIRES_AUTH

NetworkSystem::NetworkSystem()
{
}

void NetworkSystem::InitSystem(PinnedDownCore::Game* game)
{
	GameSystem::InitSystem(game);

	this->game->eventManager->AddListener(this, ScreenChangedEvent::ScreenChangedEventType);
	this->game->eventManager->AddListener(this, PointerPressedEvent::PointerPressedEventType);
}

void NetworkSystem::OnEvent(Event & newEvent)
{
	if (newEvent.GetEventType() == ScreenChangedEvent::ScreenChangedEventType)
	{
		auto screenChangedEvent = static_cast<ScreenChangedEvent&>(newEvent);
		this->OnScreenChanged(screenChangedEvent);
	}
	else if (newEvent.GetEventType() == PointerPressedEvent::PointerPressedEventType)
	{
		auto pointerPressedEvent = static_cast<PointerPressedEvent&>(newEvent);
		this->OnPointerPressed(pointerPressedEvent);
	}
}

void NetworkSystem::OnPointerPressed(PointerPressedEvent& pointerPressedEvent)
{
	this->SendPacket();
}

void NetworkSystem::OnScreenChanged(ScreenChangedEvent& screenChangedEvent)
{
	if (screenChangedEvent.newScreen == ScreenName::Login)
	{
		this->InitSocket();
	}
}

void NetworkSystem::InitSocket()
{
	this->clientSocket = ref new StreamSocket();
	this->serverHost = ref new HostName(PINNED_DOWN_SERVER_HOST);

	auto storeTask = create_task(this->clientSocket->ConnectAsync(serverHost, PINNED_DOWN_SERVER_PORT));

	storeTask.then([this](void)
	{
#ifdef REQUIRES_AUTH
		auto client = PinnedDownClient::Services::PinnedDownMobileService::GetClient();
		return client.login(azure::mobile::facebook);
	}).then([this](azure::mobile::user authUser)
	{
		if (authUser.is_authenticated())
		{

			this->connected = true;
			this->user = authUser;
#endif
			// Create the DataWriter object backed by the socket stream.  When dataWriter is deleted, it will also close the underlying stream.
			this->dataWriter = ref new DataWriter(this->clientSocket->OutputStream);
			dataWriter->UnicodeEncoding = UnicodeEncoding::Utf8;
			dataWriter->ByteOrder = ByteOrder::LittleEndian;
			this->clientActionWriter = std::make_shared<ClientActionWriter>(this->dataWriter);

			this->dataReader = ref new DataReader(this->clientSocket->InputStream);
			dataReader->UnicodeEncoding = UnicodeEncoding::Utf8;
			dataReader->ByteOrder = ByteOrder::LittleEndian;
			this->serverEventReader = std::make_shared<ServerEventReader>(this->dataReader);

			// Notify listeners.
			auto loginSuccessEvent = std::make_shared<LoginSuccessEvent>();
			this->game->eventManager->QueueEvent(loginSuccessEvent);

			// Start receive loop.
			this->RecvPacketLoop();
#ifdef REQUIRES_AUTH
		}
		else
		{
			// Notify listeners.
			auto loginErrorEvent = std::make_shared<LoginErrorEvent>(L"You must authenticate yourself in order to play Pinned Down.");
			this->game->eventManager->QueueEvent(loginErrorEvent);
		}
#endif
	}).then([this](task<void> t)
	{
		try
		{
			// Check for errors.
			t.get();
		}
		catch (Platform::Exception^ e)
		{
			// Notify listeners.
			auto loginErrorEvent = std::make_shared<LoginErrorEvent>(L"Unable to connect to server.");
			this->game->eventManager->QueueEvent(loginErrorEvent);
		}
		catch (azure::mobile::mobile_exception e)
		{
			// Notify listeners.
			auto loginErrorEvent = std::make_shared<LoginErrorEvent>(L"You must authenticate yourself in order to play Pinned Down.");
			this->game->eventManager->QueueEvent(loginErrorEvent);
		}
	});
}

void NetworkSystem::RecvPacketLoop()
{
	if (this->connected)
	{
		auto loadTask = create_task(this->dataReader->LoadAsync(4));

		loadTask.then([this](unsigned int bytesLoaded)
		{
			try
			{
				// Read server event.
				this->serverEventReader->ReadServerEvent();

				// Wait for next packet.
				this->RecvPacketLoop();
			}
			catch (Platform::Exception^ e)
			{
				OutputDebugString(e->Message->Data());
			}
		});
	}
}

void NetworkSystem::SendPacket()
{
	if (!this->connected)
	{
		return;
	}

	ClientAction clientAction = ClientAction(ClientActionType::SelectCard);
	this->clientActionWriter->WriteClientAction(clientAction);
}
<commit_msg>CHANGED: Network - Moved server port define to PinnedDownNet header.<commit_after>#include "pch.h"

#include "Game.h"
#include "Event.h"

#include "Events\LoginErrorEvent.h"
#include "Events\LoginSuccessEvent.h"
#include "Events\ScreenChangedEvent.h"
#include "Events\PointerPressedEvent.h"

#include "Systems\NetworkSystem.h"

#include "Util\StringUtils.h"

#include "PinnedDownNet.h"

using namespace concurrency;

using namespace PinnedDownCore;
using namespace PinnedDownClient::Events;
using namespace PinnedDownClient::Systems;

using namespace Windows::Networking;
using namespace Windows::Networking::Sockets;

using namespace Windows::Storage::Streams;

#define PINNED_DOWN_SERVER_HOST "localhost"
//#define REQUIRES_AUTH

NetworkSystem::NetworkSystem()
{
}

void NetworkSystem::InitSystem(PinnedDownCore::Game* game)
{
	GameSystem::InitSystem(game);

	this->game->eventManager->AddListener(this, ScreenChangedEvent::ScreenChangedEventType);
	this->game->eventManager->AddListener(this, PointerPressedEvent::PointerPressedEventType);
}

void NetworkSystem::OnEvent(Event & newEvent)
{
	if (newEvent.GetEventType() == ScreenChangedEvent::ScreenChangedEventType)
	{
		auto screenChangedEvent = static_cast<ScreenChangedEvent&>(newEvent);
		this->OnScreenChanged(screenChangedEvent);
	}
	else if (newEvent.GetEventType() == PointerPressedEvent::PointerPressedEventType)
	{
		auto pointerPressedEvent = static_cast<PointerPressedEvent&>(newEvent);
		this->OnPointerPressed(pointerPressedEvent);
	}
}

void NetworkSystem::OnPointerPressed(PointerPressedEvent& pointerPressedEvent)
{
	this->SendPacket();
}

void NetworkSystem::OnScreenChanged(ScreenChangedEvent& screenChangedEvent)
{
	if (screenChangedEvent.newScreen == ScreenName::Login)
	{
		this->InitSocket();
	}
}

void NetworkSystem::InitSocket()
{
	this->clientSocket = ref new StreamSocket();
	this->serverHost = ref new HostName(PINNED_DOWN_SERVER_HOST);

	auto storeTask = create_task(this->clientSocket->ConnectAsync(serverHost, PINNED_DOWN_SERVER_PORT));

	storeTask.then([this](void)
	{
#ifdef REQUIRES_AUTH
		auto client = PinnedDownClient::Services::PinnedDownMobileService::GetClient();
		return client.login(azure::mobile::facebook);
	}).then([this](azure::mobile::user authUser)
	{
		if (authUser.is_authenticated())
		{

			this->connected = true;
			this->user = authUser;
#endif
			// Create the DataWriter object backed by the socket stream.  When dataWriter is deleted, it will also close the underlying stream.
			this->dataWriter = ref new DataWriter(this->clientSocket->OutputStream);
			dataWriter->UnicodeEncoding = UnicodeEncoding::Utf8;
			dataWriter->ByteOrder = ByteOrder::LittleEndian;
			this->clientActionWriter = std::make_shared<ClientActionWriter>(this->dataWriter);

			this->dataReader = ref new DataReader(this->clientSocket->InputStream);
			dataReader->UnicodeEncoding = UnicodeEncoding::Utf8;
			dataReader->ByteOrder = ByteOrder::LittleEndian;
			this->serverEventReader = std::make_shared<ServerEventReader>(this->dataReader);

			// Notify listeners.
			auto loginSuccessEvent = std::make_shared<LoginSuccessEvent>();
			this->game->eventManager->QueueEvent(loginSuccessEvent);

			// Start receive loop.
			this->RecvPacketLoop();
#ifdef REQUIRES_AUTH
		}
		else
		{
			// Notify listeners.
			auto loginErrorEvent = std::make_shared<LoginErrorEvent>(L"You must authenticate yourself in order to play Pinned Down.");
			this->game->eventManager->QueueEvent(loginErrorEvent);
		}
#endif
	}).then([this](task<void> t)
	{
		try
		{
			// Check for errors.
			t.get();
		}
		catch (Platform::Exception^ e)
		{
			// Notify listeners.
			auto loginErrorEvent = std::make_shared<LoginErrorEvent>(L"Unable to connect to server.");
			this->game->eventManager->QueueEvent(loginErrorEvent);
		}
		catch (azure::mobile::mobile_exception e)
		{
			// Notify listeners.
			auto loginErrorEvent = std::make_shared<LoginErrorEvent>(L"You must authenticate yourself in order to play Pinned Down.");
			this->game->eventManager->QueueEvent(loginErrorEvent);
		}
	});
}

void NetworkSystem::RecvPacketLoop()
{
	if (this->connected)
	{
		auto loadTask = create_task(this->dataReader->LoadAsync(4));

		loadTask.then([this](unsigned int bytesLoaded)
		{
			try
			{
				// Read server event.
				this->serverEventReader->ReadServerEvent();

				// Wait for next packet.
				this->RecvPacketLoop();
			}
			catch (Platform::Exception^ e)
			{
				OutputDebugString(e->Message->Data());
			}
		});
	}
}

void NetworkSystem::SendPacket()
{
	if (!this->connected)
	{
		return;
	}

	ClientAction clientAction = ClientAction(ClientActionType::SelectCard);
	this->clientActionWriter->WriteClientAction(clientAction);
}
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2004 by Stanislav Karchebny                             *
 *   Stanislav.Karchebny@kdemail.net                                       *
 *                                                                         *
 *   Licensed under GPL.                                                   *
 ***************************************************************************/

#include "myarticle.h"
#include "librss/tools_p.h"

#include <qdatetime.h>
#include <qregexp.h>

#include <krfcdate.h>
#include <kdebug.h>
#include <kurl.h>

using namespace Akregator;
using namespace RSS;

struct MyArticle::Private : public RSS::Shared
{
    Article article;
    QDateTime fetchDate;
    QString title;
    int status;
    bool keep;
};

MyArticle::MyArticle() : d(new Private)
{
}

MyArticle::MyArticle(Article article) : d(new Private)
{
    d->keep = false;
    d->article = article;
    d->fetchDate = QDateTime::currentDateTime();

    if (article.title().isEmpty())
        d->title=buildTitle();
    else
        d->title=article.title();
    d->status=d->article.meta("status").toInt();
}

MyArticle::MyArticle(const MyArticle &other) : d(new Private)
{
    *this = other;
}

MyArticle::~MyArticle()
{
    if (d->deref())
        delete d;
}

MyArticle &MyArticle::operator=(const MyArticle &other)
{
    if (this != &other) {
        other.d->ref();
        if (d && d->deref())
            delete d;
        d = other.d;
    }
    return *this;
}

void MyArticle::offsetFetchTime(int secs)
{
    d->fetchDate=d->fetchDate.addSecs(secs);
}

bool MyArticle::operator<(const MyArticle &other) const
{
    return pubDate() > other.pubDate();
}

bool MyArticle::operator>(const MyArticle &other) const
{
    return pubDate() < other.pubDate();
}

bool MyArticle::operator==(const MyArticle &other) const
{
    return (d->article.guid() == other.d->article.guid());
}

int MyArticle::status() const
{
    return d->status;
}

void MyArticle::setStatus(int status)
{
    d->status=status;
}

QString MyArticle::title() const
{
    return d->title;
}

const KURL &MyArticle::link() const
{
    return d->article.link();
}

QString MyArticle::description() const
{
    return d->article.description();
}

QString MyArticle::guid() const
{
    return d->article.guid();
}

const KURL &MyArticle::commentsLink() const
{
    return d->article.commentsLink();
}

int MyArticle::comments() const
{
    return d->article.comments();
}

bool MyArticle::guidIsPermaLink() const
{
    return d->article.guidIsPermaLink();
}

bool MyArticle::keep() const
{
    return d->keep;
}

void MyArticle::setKeep(bool keep)
{
    d->keep = keep;
}

const QDateTime &MyArticle::pubDate() const
{
    return d->article.pubDate().isValid() ? d->article.pubDate()
                                          : d->fetchDate;
}

KURLLabel *MyArticle::widget(QWidget *parent, const char *name) const
{
    return d->article.widget(parent, name);
}

void MyArticle::dumpXmlData( QDomElement parent, QDomDocument doc ) const
{
    QDomElement tnode = doc.createElement( "title" );
    QDomText t=doc.createTextNode( title() );
    tnode.appendChild(t);
    parent.appendChild(tnode);

    if (link().isValid())
    {
        QDomElement lnode = doc.createElement( "link" );
        QDomText ht=doc.createTextNode(link().url());
        lnode.appendChild(ht);
        parent.appendChild(lnode);
    }

    if (!description().isEmpty())
    {
        QDomElement snode = doc.createElement( "description" );
        QDomCDATASection dt=doc.createCDATASection( description() );
        snode.appendChild(dt);
        parent.appendChild(snode);
    }

    if (!guid().isEmpty())
    {
        QDomElement gnode = doc.createElement( "guid" );
        gnode.setAttribute("isPermaLink",guidIsPermaLink()?"true":"false");
        QDomText gt=doc.createTextNode(guid());
        gnode.appendChild(gt);
        parent.appendChild(gnode);
    }

    if (pubDate().isValid())
    {
        QDomElement pnode = doc.createElement( "pubDate" );
        QDomText dat=doc.createTextNode(KRFCDate::rfc2822DateString(pubDate().toTime_t()));
        pnode.appendChild(dat);
        parent.appendChild(pnode);
    }

    if (commentsLink().isValid())
    {
        QDomElement lnode = doc.createElement( "wfw:comment" );
        QDomText ht=doc.createTextNode(commentsLink().url());
        lnode.appendChild(ht);
        parent.appendChild(lnode);
    }

    if (comments())
    {
        QDomElement lnode = doc.createElement( "slash:comments" );
        QDomText ht=doc.createTextNode(QString::number(comments()));
        lnode.appendChild(ht);
        parent.appendChild(lnode);
    }

    QDomElement metanode = doc.createElement( "metaInfo:meta" );
    metanode.setAttribute("type","status");

    QDomText stat=doc.createTextNode(QString::number(d->status));
    metanode.appendChild(stat);
    parent.appendChild(metanode);
}

QString MyArticle::buildTitle()
{
    QString s=d->article.description();
    int i=s.find('>',500); /*avoid processing too much */
    if (i != -1)
        s=s.left(i+1);
    QRegExp rx("(<([^\\s>]*)(?:[^>]*)>)[^<]*", false);
    QString tagName, toReplace, replaceWith;
    while (rx.search(s) != -1 )
    {
        tagName=rx.cap(2);
        if (tagName=="SCRIPT"||tagName=="script")
            toReplace=rx.cap(0); // strip tag AND tag contents
        else if (tagName.startsWith("br") || tagName.startsWith("BR"))
        {
            toReplace=rx.cap(1);
            replaceWith=" ";
        }
        else
            toReplace=rx.cap(1);  // strip just tag
        s=s.replace(s.find(toReplace),toReplace.length(),replaceWith); // do the deed
    }
    if (s.length()> 90)
        s=s.left(90)+"...";
    return s.simplifyWhiteSpace();
}
<commit_msg>Added loading/saving of keep flag. So only the GUI stuff related to keep is left to be done.<commit_after>/***************************************************************************
 *   Copyright (C) 2004 by Stanislav Karchebny                             *
 *   Stanislav.Karchebny@kdemail.net                                       *
 *                                                                         *
 *   Licensed under GPL.                                                   *
 ***************************************************************************/

#include "myarticle.h"
#include "librss/tools_p.h"

#include <qdatetime.h>
#include <qregexp.h>

#include <krfcdate.h>
#include <kdebug.h>
#include <kurl.h>

using namespace Akregator;
using namespace RSS;

struct MyArticle::Private : public RSS::Shared
{
    Article article;
    QDateTime fetchDate;
    QString title;
    int status;
    bool keep;
};

MyArticle::MyArticle() : d(new Private)
{
}

MyArticle::MyArticle(Article article) : d(new Private)
{
    d->article = article;
    d->fetchDate = QDateTime::currentDateTime();

    if (article.title().isEmpty())
        d->title=buildTitle();
    else
        d->title=article.title();
    d->status=d->article.meta("status").toInt();

    d->keep = article.meta("keep") == "true" ? true : false;

    if (d->keep)
        kdDebug() << "KEEP" << d->title << endl;
}

MyArticle::MyArticle(const MyArticle &other) : d(new Private)
{
    *this = other;
}

MyArticle::~MyArticle()
{
    if (d->deref())
        delete d;
}

MyArticle &MyArticle::operator=(const MyArticle &other)
{
    if (this != &other) {
        other.d->ref();
        if (d && d->deref())
            delete d;
        d = other.d;
    }
    return *this;
}

void MyArticle::offsetFetchTime(int secs)
{
    d->fetchDate=d->fetchDate.addSecs(secs);
}

bool MyArticle::operator<(const MyArticle &other) const
{
    return pubDate() > other.pubDate();
}

bool MyArticle::operator>(const MyArticle &other) const
{
    return pubDate() < other.pubDate();
}

bool MyArticle::operator==(const MyArticle &other) const
{
    return (d->article.guid() == other.d->article.guid());
}

int MyArticle::status() const
{
    return d->status;
}

void MyArticle::setStatus(int status)
{
    d->status=status;
}

QString MyArticle::title() const
{
    return d->title;
}

const KURL &MyArticle::link() const
{
    return d->article.link();
}

QString MyArticle::description() const
{
    return d->article.description();
}

QString MyArticle::guid() const
{
    return d->article.guid();
}

const KURL &MyArticle::commentsLink() const
{
    return d->article.commentsLink();
}

int MyArticle::comments() const
{
    return d->article.comments();
}

bool MyArticle::guidIsPermaLink() const
{
    return d->article.guidIsPermaLink();
}

bool MyArticle::keep() const
{
    return d->keep;
}

void MyArticle::setKeep(bool keep)
{
    d->keep = keep;
}

const QDateTime &MyArticle::pubDate() const
{
    return d->article.pubDate().isValid() ? d->article.pubDate()
                                          : d->fetchDate;
}

KURLLabel *MyArticle::widget(QWidget *parent, const char *name) const
{
    return d->article.widget(parent, name);
}

void MyArticle::dumpXmlData( QDomElement parent, QDomDocument doc ) const
{
    QDomElement tnode = doc.createElement( "title" );
    QDomText t=doc.createTextNode( title() );
    tnode.appendChild(t);
    parent.appendChild(tnode);

    if (link().isValid())
    {
        QDomElement lnode = doc.createElement( "link" );
        QDomText ht=doc.createTextNode(link().url());
        lnode.appendChild(ht);
        parent.appendChild(lnode);
    }

    if (!description().isEmpty())
    {
        QDomElement snode = doc.createElement( "description" );
        QDomCDATASection dt=doc.createCDATASection( description() );
        snode.appendChild(dt);
        parent.appendChild(snode);
    }

    if (!guid().isEmpty())
    {
        QDomElement gnode = doc.createElement( "guid" );
        gnode.setAttribute("isPermaLink",guidIsPermaLink()?"true":"false");
        QDomText gt=doc.createTextNode(guid());
        gnode.appendChild(gt);
        parent.appendChild(gnode);
    }

    if (pubDate().isValid())
    {
        QDomElement pnode = doc.createElement( "pubDate" );
        QDomText dat=doc.createTextNode(KRFCDate::rfc2822DateString(pubDate().toTime_t()));
        pnode.appendChild(dat);
        parent.appendChild(pnode);
    }

    if (commentsLink().isValid())
    {
        QDomElement lnode = doc.createElement( "wfw:comment" );
        QDomText ht=doc.createTextNode(commentsLink().url());
        lnode.appendChild(ht);
        parent.appendChild(lnode);
    }

    if (comments())
    {
        QDomElement lnode = doc.createElement( "slash:comments" );
        QDomText ht=doc.createTextNode(QString::number(comments()));
        lnode.appendChild(ht);
        parent.appendChild(lnode);
    }

    QDomElement metanode = doc.createElement( "metaInfo:meta" );
    metanode.setAttribute("type","status");
    QDomText stat=doc.createTextNode(QString::number(d->status));
    metanode.appendChild(stat);
    parent.appendChild(metanode);

    if ( d->keep )
    {
        metanode = doc.createElement( "metaInfo:meta" );
        metanode.setAttribute("type", "keep");
        metanode.appendChild(doc.createTextNode( d-> keep ? "true" : "false"));
        parent.appendChild(metanode);
    }
}

QString MyArticle::buildTitle()
{
    QString s=d->article.description();
    int i=s.find('>',500); /*avoid processing too much */
    if (i != -1)
        s=s.left(i+1);
    QRegExp rx("(<([^\\s>]*)(?:[^>]*)>)[^<]*", false);
    QString tagName, toReplace, replaceWith;
    while (rx.search(s) != -1 )
    {
        tagName=rx.cap(2);
        if (tagName=="SCRIPT"||tagName=="script")
            toReplace=rx.cap(0); // strip tag AND tag contents
        else if (tagName.startsWith("br") || tagName.startsWith("BR"))
        {
            toReplace=rx.cap(1);
            replaceWith=" ";
        }
        else
            toReplace=rx.cap(1);  // strip just tag
        s=s.replace(s.find(toReplace),toReplace.length(),replaceWith); // do the deed
    }
    if (s.length()> 90)
        s=s.left(90)+"...";
    return s.simplifyWhiteSpace();
}
<|endoftext|>


<commit_before>/***************************************************************************
 *     Copyright (C) 2004 by Sashmit Bhaduri                               *
 *     smt@vfemail.net                                                     *
 *                                                                         *
 *     Licensed under GPL.                                                 *
 ***************************************************************************/

#include "tabwidget.h"

#include <qstyle.h>
#include <qapplication.h>
#include <qiconset.h>

#include <kdebug.h>
#include <ktabwidget.h>
#include <ktabbar.h>
#include <kpopupmenu.h>
#include <krun.h>
#include <klocale.h>
#include <khtmlview.h>
#include <khtml_part.h>
#include <kiconloader.h>

using namespace Akregator;

TabWidget::TabWidget(QWidget * parent, const char *name)
        :KTabWidget(parent, name), m_CurrentMaxLength(30)
{
    setTabReorderingEnabled(true);
    connect( this, SIGNAL( currentChanged(QWidget *) ), this,
            SLOT( slotTabChanged(QWidget *) ) );
}

TabWidget::~TabWidget()
{
}

void TabWidget::addFrame(Frame *f)
{
    if (!f || !f->widget()) return;
    m_frames.insert(f->widget(), f);
    addTab(f->widget(), f->title());
}

Frame *TabWidget::currentFrame()
{
    QWidget *w=currentPage();
    if (!w) return 0;
    return m_frames[w];
}

void TabWidget::slotTabChanged(QWidget *w)
{
    emit currentFrameChanged(m_frames[w]);
}

void TabWidget::removeFrame(Frame *f)
{
    m_frames.remove(f->widget());
    removePage(f->widget());
}

// copied wholesale from KonqFrameTabs

unsigned int TabWidget::tabBarWidthForMaxChars( uint maxLength )
{
    int hframe, overlap;
    hframe    = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, this );
    overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, this );

    QFontMetrics fm = tabBar()->fontMetrics();
    int x = 0;
    for( int i=0; i < count(); ++i ) {
        Frame *f=m_frames[page(i)];
        QString newTitle=f->title();
        if ( newTitle.length() > maxLength )
            newTitle = newTitle.left( maxLength-3 ) + "...";

        QTab* tab = tabBar()->tabAt( i );
        int lw = fm.width( newTitle );
        int iw = 0;
        if ( tab->iconSet() )
            iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;

        x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this,                             QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), QStyleOption( tab ) ) ).width();
    }
    return x;
}

void TabWidget::setTitle( const QString &title , QWidget* sender)
{
    removeTabToolTip( sender );

    Frame *f=m_frames[sender];
    if (f)
        f->setTitle(title);

    uint lcw=0, rcw=0;
    int tabBarHeight = tabBar()->sizeHint().height();
    if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
        lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
    if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
        rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight );
    uint maxTabBarWidth = width() - lcw - rcw;

    uint newMaxLength=30;
    for ( ; newMaxLength > 3; newMaxLength-- ) {
        if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
            break;
    }
    QString newTitle = title;
    if ( newTitle.length() > newMaxLength )
    {
        setTabToolTip( sender, newTitle );
        newTitle = newTitle.left( newMaxLength-3 ) + "...";
    }

    newTitle.replace( '&', "&&" );
    if ( tabLabel( sender ) != newTitle )
        changeTab( sender, newTitle );

    if( newMaxLength != m_CurrentMaxLength )
    {
        for( int i = 0; i < count(); ++i)
        {
            Frame *f=m_frames[page(i)];
            newTitle=f->title();
            removeTabToolTip( page( i ) );
            if ( newTitle.length() > newMaxLength )
            {
                setTabToolTip( page( i ), newTitle );
                newTitle = newTitle.left( newMaxLength-3 ) + "...";
            }

            newTitle.replace( '&', "&&" );
            if ( newTitle != tabLabel( page( i ) ) )
                    changeTab( page( i ), newTitle );
        }
        m_CurrentMaxLength = newMaxLength;
    }
}

void TabWidget::contextMenu(int i, const QPoint &p)
{
   currentItem = page(i);
   KPopupMenu popup;
   //popup.insertTitle(tabLabel(currentItem));
   int detachTab = popup.insertItem( SmallIcon("tab_breakoff"), i18n("Detach Tab"), this, SLOT( slotDetachTab() ) );
   //popup.insertSeparator();
   int closeTab = popup.insertItem( SmallIcon("tab_remove"), i18n("Close Tab"), this, SLOT( slotCloseTab() ) );
   if(indexOf(currentItem) == 0) { // you can't detach or close articles tab..
      popup.setItemEnabled(detachTab, false);
      popup.setItemEnabled(closeTab, false);
   }
   popup.exec(p);
}

void TabWidget::slotDetachTab()
{
   if(!currentItem) return;
   KURL url;
   if (KHTMLView *view = dynamic_cast<KHTMLView*>(currentItem)) url = view->part()->url();
   else return;
   KRun::runURL(url.prettyURL(),"text/html", false, false);
   removePage(currentItem);
}

void TabWidget::slotCloseTab()
{
   if(!currentItem) return;
   removePage(currentItem);
}

#include "tabwidget.moc"

// vim: set et ts=4 sts=4 sw=4:
<commit_msg>disable tab re-ordering for now since it is buggy if you move the articles tab<commit_after>/***************************************************************************
 *     Copyright (C) 2004 by Sashmit Bhaduri                               *
 *     smt@vfemail.net                                                     *
 *                                                                         *
 *     Licensed under GPL.                                                 *
 ***************************************************************************/

#include "tabwidget.h"

#include <qstyle.h>
#include <qapplication.h>
#include <qiconset.h>

#include <kdebug.h>
#include <ktabwidget.h>
#include <ktabbar.h>
#include <kpopupmenu.h>
#include <krun.h>
#include <klocale.h>
#include <khtmlview.h>
#include <khtml_part.h>
#include <kiconloader.h>

using namespace Akregator;

TabWidget::TabWidget(QWidget * parent, const char *name)
        :KTabWidget(parent, name), m_CurrentMaxLength(30)
{
    setTabReorderingEnabled(false);
    connect( this, SIGNAL( currentChanged(QWidget *) ), this,
            SLOT( slotTabChanged(QWidget *) ) );
}

TabWidget::~TabWidget()
{
}

void TabWidget::addFrame(Frame *f)
{
    if (!f || !f->widget()) return;
    m_frames.insert(f->widget(), f);
    addTab(f->widget(), f->title());
}

Frame *TabWidget::currentFrame()
{
    QWidget *w=currentPage();
    if (!w) return 0;
    return m_frames[w];
}

void TabWidget::slotTabChanged(QWidget *w)
{
    emit currentFrameChanged(m_frames[w]);
}

void TabWidget::removeFrame(Frame *f)
{
    m_frames.remove(f->widget());
    removePage(f->widget());
}

// copied wholesale from KonqFrameTabs

unsigned int TabWidget::tabBarWidthForMaxChars( uint maxLength )
{
    int hframe, overlap;
    hframe    = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabHSpace, this );
    overlap = tabBar()->style().pixelMetric( QStyle::PM_TabBarTabOverlap, this );

    QFontMetrics fm = tabBar()->fontMetrics();
    int x = 0;
    for( int i=0; i < count(); ++i ) {
        Frame *f=m_frames[page(i)];
        QString newTitle=f->title();
        if ( newTitle.length() > maxLength )
            newTitle = newTitle.left( maxLength-3 ) + "...";

        QTab* tab = tabBar()->tabAt( i );
        int lw = fm.width( newTitle );
        int iw = 0;
        if ( tab->iconSet() )
            iw = tab->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 4;

        x += ( tabBar()->style().sizeFromContents( QStyle::CT_TabBarTab, this,                             QSize( QMAX( lw + hframe + iw, QApplication::globalStrut().width() ), 0 ), QStyleOption( tab ) ) ).width();
    }
    return x;
}

void TabWidget::setTitle( const QString &title , QWidget* sender)
{
    removeTabToolTip( sender );

    Frame *f=m_frames[sender];
    if (f)
        f->setTitle(title);

    uint lcw=0, rcw=0;
    int tabBarHeight = tabBar()->sizeHint().height();
    if ( cornerWidget( TopLeft ) && cornerWidget( TopLeft )->isVisible() )
        lcw = QMAX( cornerWidget( TopLeft )->width(), tabBarHeight );
    if ( cornerWidget( TopRight ) && cornerWidget( TopRight )->isVisible() )
        rcw = QMAX( cornerWidget( TopRight )->width(), tabBarHeight );
    uint maxTabBarWidth = width() - lcw - rcw;

    uint newMaxLength=30;
    for ( ; newMaxLength > 3; newMaxLength-- ) {
        if ( tabBarWidthForMaxChars( newMaxLength ) < maxTabBarWidth )
            break;
    }
    QString newTitle = title;
    if ( newTitle.length() > newMaxLength )
    {
        setTabToolTip( sender, newTitle );
        newTitle = newTitle.left( newMaxLength-3 ) + "...";
    }

    newTitle.replace( '&', "&&" );
    if ( tabLabel( sender ) != newTitle )
        changeTab( sender, newTitle );

    if( newMaxLength != m_CurrentMaxLength )
    {
        for( int i = 0; i < count(); ++i)
        {
            Frame *f=m_frames[page(i)];
            newTitle=f->title();
            removeTabToolTip( page( i ) );
            if ( newTitle.length() > newMaxLength )
            {
                setTabToolTip( page( i ), newTitle );
                newTitle = newTitle.left( newMaxLength-3 ) + "...";
            }

            newTitle.replace( '&', "&&" );
            if ( newTitle != tabLabel( page( i ) ) )
                    changeTab( page( i ), newTitle );
        }
        m_CurrentMaxLength = newMaxLength;
    }
}

void TabWidget::contextMenu(int i, const QPoint &p)
{
   currentItem = page(i);
   KPopupMenu popup;
   //popup.insertTitle(tabLabel(currentItem));
   int detachTab = popup.insertItem( SmallIcon("tab_breakoff"), i18n("Detach Tab"), this, SLOT( slotDetachTab() ) );
   //popup.insertSeparator();
   int closeTab = popup.insertItem( SmallIcon("tab_remove"), i18n("Close Tab"), this, SLOT( slotCloseTab() ) );
   if(indexOf(currentItem) == 0) { // you can't detach or close articles tab..
      popup.setItemEnabled(detachTab, false);
      popup.setItemEnabled(closeTab, false);
   }
   popup.exec(p);
}

void TabWidget::slotDetachTab()
{
   if(!currentItem) return;
   KURL url;
   if (KHTMLView *view = dynamic_cast<KHTMLView*>(currentItem)) url = view->part()->url();
   else return;
   KRun::runURL(url.prettyURL(),"text/html", false, false);
   removePage(currentItem);
}

void TabWidget::slotCloseTab()
{
   if(!currentItem) return;
   removePage(currentItem);
}

#include "tabwidget.moc"

// vim: set et ts=4 sts=4 sw=4:
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright (c) 2016, ROBOTIS CO., LTD.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
*   list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
*   this list of conditions and the following disclaimer in the documentation
*   and/or other materials provided with the distribution.
*
* * Neither the name of ROBOTIS nor the names of its
*   contributors may be used to endorse or promote products derived from
*   this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*******************************************************************************/

/* Author: Taehoon Lim (Darby), zerom */

#include "dynamixel_workbench_toolbox/dynamixel_tool.h"

using namespace dynamixel_tool;

static inline std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
    return s;
}
static inline std::string &rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
    return s;
}
static inline std::string &trim(std::string &s) {
    return ltrim(rtrim(s));
}
static inline std::vector<std::string> split(const std::string &text, char sep) {
    std::vector<std::string> tokens;
    std::size_t start = 0, end = 0;
    while((end = text.find(sep, start)) != (std::string::npos)) {
        tokens.push_back(text.substr(start, end - start));
        trim(tokens.back());
        start = end + 1;
    }
    tokens.push_back(text.substr(start));
    trim(tokens.back());
    return tokens;
}

DynamixelTool::DynamixelTool(uint8_t id, uint16_t model_number)
    :id_(0),
     model_number_(0),
     model_name_(""),
     item_path_(""),
     name_path_("")
{
  id_ = id;

  getModelName(model_number);
  getModelItem();
}

DynamixelTool::DynamixelTool(uint8_t id, std::string model_name)
    :id_(0),
     model_number_(0),
     model_name_(""),
     item_path_(""),
     name_path_("")
{
  id_         = id;
  model_name_ = model_name;

  getModelItem();
}

DynamixelTool::~DynamixelTool(){}

bool DynamixelTool::getModelName(uint16_t model_number)
{
  name_path_  = ros::package::getPath("dynamixel_workbench_toolbox") + "/dynamixel/model_info.list";

  std::ifstream file(name_path_.c_str());
  if (file.is_open())
  {
    std::string input_str;

    while (!file.eof())
    {
      std::getline(file, input_str);

      // remove comment ( # )
      std::size_t pos = input_str.find("#");
      if (pos != std::string::npos)
      {
        input_str = input_str.substr(0,pos);
      }

      std::vector<std::string> tokens = split(input_str, '|');
      if (tokens.size() != 2)
        continue;

      if (model_number == std::atoi(tokens[0].c_str()))
      {
        model_number_ = model_number;
        model_name_ = tokens[1];
      }
    }
    file.close();
  }
  else
  {
    ROS_ERROR("Unable to open model_info file : %s", name_path_.c_str());
    ros::shutdown();
  }
}

bool DynamixelTool::getModelPath()
{
  std::string dynamixel_series = "";
  dynamixel_series = model_name_.substr(0,2);

  item_path_  = ros::package::getPath("dynamixel_workbench_toolbox") + "/dynamixel";

  item_path_ = item_path_ + "/models" + "/" + dynamixel_series + "/" + model_name_ + ".device";
}

bool DynamixelTool::getModelItem()
{
  getModelPath();

  std::ifstream file(item_path_.c_str());
  if (file.is_open())
  {
    std::string session = "";
    std::string input_str;

    while (!file.eof())
    {
      std::getline(file, input_str);

      // remove comment ( # )
      std::size_t pos = input_str.find("#");
      if (pos != std::string::npos)
      {
        input_str = input_str.substr(0,pos);
      }

      // trim
      input_str = trim(input_str);
      if (input_str == "")
        continue;

      // find session;
      if (!input_str.compare(0, 1, "[") && !input_str.compare(input_str.size()-1, 1, "]"))
      {
        input_str = input_str.substr(1, input_str.size()-2);
        std::transform(input_str.begin(), input_str.end(), input_str.begin(), ::tolower);
        session = trim(input_str);
        continue;
      }

      if (session == "type info")
      {
        std::vector<std::string> tokens = split(input_str, '=');
        if (tokens.size() != 2)
          continue;

        if (tokens[0] == "torque_to_current_value_ratio")
          torque_to_current_value_ratio_ = std::atof(tokens[1].c_str());
        else if (tokens[0] == "velocity_to_value_ratio")
          velocity_to_value_ratio_ = std::atof(tokens[1].c_str());
        else if (tokens[0] == "value_of_0_radian_position")
          value_of_0_radian_position_ = std::atoi(tokens[1].c_str());
        else if (tokens[0] == "value_of_min_radian_position")
          value_of_min_radian_position_ = std::atoi(tokens[1].c_str());
        else if (tokens[0] == "value_of_max_radian_position")
          value_of_max_radian_position_ = std::atoi(tokens[1].c_str());
        else if (tokens[0] == "min_radian")
          min_radian_ = std::atof(tokens[1].c_str());
        else if (tokens[0] == "max_radian")
          max_radian_ = std::atof(tokens[1].c_str());
      }
      else if (session == "baud rate")
      {
        std::vector<std::string> tokens = split(input_str, '|');
        if(tokens.size() != 2)
          continue;

        baud_rate_table_[std::atoi(tokens[0].c_str())] = std::atoi(tokens[1].c_str());
      }
      else if (session == "control table")
      {
        std::vector<std::string> tokens = split(input_str, '|');
        if(tokens.size() != 5)
          continue;

        ControlTableItem *item = new ControlTableItem;
        item->item_name = tokens[1];
        item->address = std::atoi(tokens[0].c_str());
        item->data_length = std::atoi(tokens[2].c_str());
        if(tokens[3] == "R")
            item->access_type = READ;
        else if(tokens[3] == "RW")
            item->access_type = READ_WRITE;
        if(tokens[4] == "EEPROM")
            item->memory_type = EEPROM;
        else if(tokens[4] == "RAM")
            item->memory_type = RAM;

        ctrl_table_[item->item_name] = item;
      }
    }
    file.close();
  }
  else
  {
    ROS_ERROR("Unable to open .device file : %s", item_path_.c_str());
    ros::shutdown();
  }
}
<commit_msg>update get model path<commit_after>/*******************************************************************************
* Copyright (c) 2016, ROBOTIS CO., LTD.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
*   list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
*   this list of conditions and the following disclaimer in the documentation
*   and/or other materials provided with the distribution.
*
* * Neither the name of ROBOTIS nor the names of its
*   contributors may be used to endorse or promote products derived from
*   this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*******************************************************************************/

/* Author: Taehoon Lim (Darby), zerom */

#include "dynamixel_workbench_toolbox/dynamixel_tool.h"

using namespace dynamixel_tool;

static inline std::string &ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
    return s;
}
static inline std::string &rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
    return s;
}
static inline std::string &trim(std::string &s) {
    return ltrim(rtrim(s));
}
static inline std::vector<std::string> split(const std::string &text, char sep) {
    std::vector<std::string> tokens;
    std::size_t start = 0, end = 0;
    while((end = text.find(sep, start)) != (std::string::npos)) {
        tokens.push_back(text.substr(start, end - start));
        trim(tokens.back());
        start = end + 1;
    }
    tokens.push_back(text.substr(start));
    trim(tokens.back());
    return tokens;
}

DynamixelTool::DynamixelTool(uint8_t id, uint16_t model_number)
    :id_(0),
     model_number_(0),
     model_name_(""),
     item_path_(""),
     name_path_("")
{
  id_ = id;

  getModelName(model_number);
  getModelItem();
}

DynamixelTool::DynamixelTool(uint8_t id, std::string model_name)
    :id_(0),
     model_number_(0),
     model_name_(""),
     item_path_(""),
     name_path_("")
{
  id_         = id;
  model_name_ = model_name;

  getModelItem();
}

DynamixelTool::~DynamixelTool(){}

bool DynamixelTool::getModelName(uint16_t model_number)
{
  name_path_  = ros::package::getPath("dynamixel_workbench_toolbox") + "/dynamixel/model_info.list";

  std::ifstream file(name_path_.c_str());
  if (file.is_open())
  {
    std::string input_str;

    while (!file.eof())
    {
      std::getline(file, input_str);

      // remove comment ( # )
      std::size_t pos = input_str.find("#");
      if (pos != std::string::npos)
      {
        input_str = input_str.substr(0,pos);
      }

      std::vector<std::string> tokens = split(input_str, '|');
      if (tokens.size() != 2)
        continue;

      if (model_number == std::atoi(tokens[0].c_str()))
      {
        model_number_ = model_number;
        model_name_ = tokens[1];
      }
    }
    file.close();
  }
  else
  {
    ROS_ERROR("Unable to open model_info file : %s", name_path_.c_str());
    ros::shutdown();
  }
}

bool DynamixelTool::getModelPath()
{
  std::string dynamixel_series = "";
  dynamixel_series = model_name_.substr(0,3);

  if (dynamixel_series.find("_") != std::string::npos)
    dynamixel_series.erase(2,3);

  item_path_  = ros::package::getPath("dynamixel_workbench_toolbox") + "/dynamixel";

  item_path_ = item_path_ + "/models" + "/" + dynamixel_series + "/" + model_name_ + ".device";
}

bool DynamixelTool::getModelItem()
{
  getModelPath();

  std::ifstream file(item_path_.c_str());
  if (file.is_open())
  {
    std::string session = "";
    std::string input_str;

    while (!file.eof())
    {
      std::getline(file, input_str);

      // remove comment ( # )
      std::size_t pos = input_str.find("#");
      if (pos != std::string::npos)
      {
        input_str = input_str.substr(0,pos);
      }

      // trim
      input_str = trim(input_str);
      if (input_str == "")
        continue;

      // find session;
      if (!input_str.compare(0, 1, "[") && !input_str.compare(input_str.size()-1, 1, "]"))
      {
        input_str = input_str.substr(1, input_str.size()-2);
        std::transform(input_str.begin(), input_str.end(), input_str.begin(), ::tolower);
        session = trim(input_str);
        continue;
      }

      if (session == "type info")
      {
        std::vector<std::string> tokens = split(input_str, '=');
        if (tokens.size() != 2)
          continue;

        if (tokens[0] == "torque_to_current_value_ratio")
          torque_to_current_value_ratio_ = std::atof(tokens[1].c_str());
        else if (tokens[0] == "velocity_to_value_ratio")
          velocity_to_value_ratio_ = std::atof(tokens[1].c_str());
        else if (tokens[0] == "value_of_0_radian_position")
          value_of_0_radian_position_ = std::atoi(tokens[1].c_str());
        else if (tokens[0] == "value_of_min_radian_position")
          value_of_min_radian_position_ = std::atoi(tokens[1].c_str());
        else if (tokens[0] == "value_of_max_radian_position")
          value_of_max_radian_position_ = std::atoi(tokens[1].c_str());
        else if (tokens[0] == "min_radian")
          min_radian_ = std::atof(tokens[1].c_str());
        else if (tokens[0] == "max_radian")
          max_radian_ = std::atof(tokens[1].c_str());
      }
      else if (session == "baud rate")
      {
        std::vector<std::string> tokens = split(input_str, '|');
        if(tokens.size() != 2)
          continue;

        baud_rate_table_[std::atoi(tokens[0].c_str())] = std::atoi(tokens[1].c_str());
      }
      else if (session == "control table")
      {
        std::vector<std::string> tokens = split(input_str, '|');
        if(tokens.size() != 5)
          continue;

        ControlTableItem *item = new ControlTableItem;
        item->item_name = tokens[1];
        item->address = std::atoi(tokens[0].c_str());
        item->data_length = std::atoi(tokens[2].c_str());
        if(tokens[3] == "R")
            item->access_type = READ;
        else if(tokens[3] == "RW")
            item->access_type = READ_WRITE;
        if(tokens[4] == "EEPROM")
            item->memory_type = EEPROM;
        else if(tokens[4] == "RAM")
            item->memory_type = RAM;

        ctrl_table_[item->item_name] = item;
      }
    }
    file.close();
  }
  else
  {
    ROS_ERROR("Unable to open .device file : %s", item_path_.c_str());
    ros::shutdown();
  }
}
<|endoftext|>


<commit_before>/** \brief Utility for checking which ISBNS can be found on archive.org.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2021 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <atomic>
#include <chrono>
#include <iostream>
#include <deque>
#include <mutex>
#include <thread>
#include <cstdio>
#include <cstdlib>
#include "Downloader.h"
#include "FileUtil.h"
#include "StringUtil.h"
#include "MARC.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--summarize-tags] [--verbose] worker_thread_count marc_data isbn_list_output");
}

std::atomic<bool> work_available(true);

void WorkerThread(Downloader * const downloader, std::deque<std::set<std::string>> * const task_queue,
                  std::mutex * const task_queue_mutex, unsigned * const isbn_found_count, File * const isbn_list_output,
                  std::mutex * const output_mutex)
{
    std::set<std::string> isbns;
    for (;;) {
        {
            std::lock_guard<std::mutex> task_queue_mutex_locker(*task_queue_mutex);
            if (not task_queue->empty()) {
                isbns = task_queue->front();
                task_queue->pop_front();
            }
        }

        if (isbns.empty()) {
            if (not work_available)
                return;
            std::this_thread::sleep_for(std::chrono::seconds(20));
            continue;
        }

        for (const auto &isbn : isbns) {
            const std::string url("https://archive.org/metadata/isbn_" + isbn + "/created");
            if (not downloader->newUrl(url)) {
                std::lock_guard<std::mutex> output_mutex_locker(*output_mutex);
                LOG_WARNING("URL \"" + url + " failed to download! ("
                            + downloader->getLastErrorMessage() + ")");
                continue;
            }

            if (downloader->getMessageBody().find("result") != std::string::npos) {
                std::lock_guard<std::mutex> output_mutex_locker(*output_mutex);
                isbn_list_output->writeln(isbn);
                ++*isbn_found_count;
                std::cout << *isbn_found_count << '\n';
                break;
            }
        }

        isbns.clear();
    }
}

void ProcessRecords(MARC::Reader * const marc_reader, std::deque<std::set<std::string>> * const task_queue,
                    std::mutex * const task_queue_mutex)
{
    unsigned record_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;
        const auto isbns(record.getISBNs());
        if (isbns.empty())
            continue;

        std::lock_guard<std::mutex> task_queue_mutex_locker(*task_queue_mutex);
        task_queue->push_back(isbns);
    }
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 4)
        Usage();

    const unsigned WORKER_THREAD_COUNT(StringUtil::ToUnsigned(argv[1]));
    std::vector<std::thread> thread_pool((WORKER_THREAD_COUNT));
    std::deque<std::set<std::string>> task_queue;
    std::mutex task_queue_mutex, output_mutex;
    unsigned isbn_found_count(0);
    auto isbn_list_output(FileUtil::OpenOutputFileOrDie(argv[3]));
    for (size_t i(0); i < WORKER_THREAD_COUNT; ++i)
        thread_pool[i] = std::thread(WorkerThread, new Downloader(), &task_queue, &task_queue_mutex,
                                     &isbn_found_count, isbn_list_output.get(), &output_mutex);

    auto marc_reader(MARC::Reader::Factory(argv[2]));
    ProcessRecords(marc_reader.get(), &task_queue, &task_queue_mutex);

    work_available = false; // Let our worker threads return.
    for (size_t i(0); i < WORKER_THREAD_COUNT; ++i)
        thread_pool[i].join();
    LOG_INFO("Found " + std::to_string(isbn_found_count) + " monographs on Archive.org.");

    return EXIT_SUCCESS;
}
<commit_msg>Renamed a variable.<commit_after>/** \brief Utility for checking which ISBNS can be found on archive.org.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2021 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <atomic>
#include <chrono>
#include <iostream>
#include <deque>
#include <mutex>
#include <thread>
#include <cstdio>
#include <cstdlib>
#include "Downloader.h"
#include "FileUtil.h"
#include "StringUtil.h"
#include "MARC.h"
#include "util.h"

namespace {

[[noreturn]] void Usage() {
    ::Usage("[--summarize-tags] [--verbose] worker_thread_count marc_data isbn_list_output");
}

std::atomic<bool> work_available(true);

void WorkerThread(Downloader * const downloader, std::deque<std::set<std::string>> * const task_queue,
                  std::mutex * const task_queue_mutex, unsigned * const record_found_count, File * const isbn_list_output,
                  std::mutex * const output_mutex)
{
    std::set<std::string> isbns;
    for (;;) {
        {
            std::lock_guard<std::mutex> task_queue_mutex_locker(*task_queue_mutex);
            if (not task_queue->empty()) {
                isbns = task_queue->front();
                task_queue->pop_front();
            }
        }

        if (isbns.empty()) {
            if (not work_available)
                return;
            std::this_thread::sleep_for(std::chrono::seconds(20));
            continue;
        }

        for (const auto &isbn : isbns) {
            const std::string url("https://archive.org/metadata/isbn_" + isbn + "/created");
            if (not downloader->newUrl(url)) {
                std::lock_guard<std::mutex> output_mutex_locker(*output_mutex);
                LOG_WARNING("URL \"" + url + " failed to download! ("
                            + downloader->getLastErrorMessage() + ")");
                continue;
            }

            if (downloader->getMessageBody().find("result") != std::string::npos) {
                std::lock_guard<std::mutex> output_mutex_locker(*output_mutex);
                isbn_list_output->writeln(isbn);
                ++*record_found_count;
                std::cout << *record_found_count << '\n';
                break;
            }
        }

        isbns.clear();
    }
}

void ProcessRecords(MARC::Reader * const marc_reader, std::deque<std::set<std::string>> * const task_queue,
                    std::mutex * const task_queue_mutex)
{
    unsigned record_count(0);
    while (const MARC::Record record = marc_reader->read()) {
        ++record_count;
        const auto isbns(record.getISBNs());
        if (isbns.empty())
            continue;

        std::lock_guard<std::mutex> task_queue_mutex_locker(*task_queue_mutex);
        task_queue->push_back(isbns);
    }
}

} // unnamed namespace

int Main(int argc, char *argv[]) {
    if (argc != 4)
        Usage();

    const unsigned WORKER_THREAD_COUNT(StringUtil::ToUnsigned(argv[1]));
    std::vector<std::thread> thread_pool((WORKER_THREAD_COUNT));
    std::deque<std::set<std::string>> task_queue;
    std::mutex task_queue_mutex, output_mutex;
    unsigned record_found_count(0);
    auto isbn_list_output(FileUtil::OpenOutputFileOrDie(argv[3]));
    for (size_t i(0); i < WORKER_THREAD_COUNT; ++i)
        thread_pool[i] = std::thread(WorkerThread, new Downloader(), &task_queue, &task_queue_mutex,
                                     &record_found_count, isbn_list_output.get(), &output_mutex);

    auto marc_reader(MARC::Reader::Factory(argv[2]));
    ProcessRecords(marc_reader.get(), &task_queue, &task_queue_mutex);

    work_available = false; // Let our worker threads return.
    for (size_t i(0); i < WORKER_THREAD_COUNT; ++i)
        thread_pool[i].join();
    LOG_INFO("Found " + std::to_string(record_found_count) + " monographs on Archive.org.");

    return EXIT_SUCCESS;
}
<|endoftext|>