<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkSegmentationSink.h"
#include "mitkRenderingManager.h"

namespace mitk {

SegmentationSink::SegmentationSink()
{
}

SegmentationSink::~SegmentationSink()
{
}

void SegmentationSink::Initialize(const NonBlockingAlgorithm* other)
{
  Superclass::Initialize(other);
  // sinks should be called explicitly from the tool, because otherwise the order of setting "Input" and "Group node" would matter
  UnDefineTriggerParameter("Input");

  // some basedata output
  DataTreeNode::Pointer groupNode;
  DataTree::Pointer dataTree;
  bool showResult(true);

  if (other)
  {
    other->GetPointerParameter("Group node", groupNode);
    other->GetPointerParameter("Data tree", dataTree);
    other->GetParameter("Show result", showResult);
  }

  SetPointerParameter("Group node", groupNode );
  SetPointerParameter("Data tree", dataTree );
  SetParameter("Show result", showResult );
}

bool SegmentationSink::ReadyToRun()
{
  Image::Pointer image;
  GetPointerParameter("Input", image);

  DataTreeNode::Pointer groupNode;
  GetPointerParameter("Group node", groupNode);

  return image.IsNotNull() && groupNode.IsNotNull();
}

bool SegmentationSink::ThreadedUpdateFunction()
{
  return true;
}

/// to be called by subclasses when they want to insert some resulting object (binary image, surface, ...) into the data tree
void SegmentationSink::InsertBelowGroupNode(mitk::DataTreeNode* node)
{
  DataTree::Pointer dataTree;
  GetPointerParameter("Data tree", dataTree );

  DataTreeNode* groupNode = GetGroupNode();

  DataTreeIteratorClone treeIter = dataTree->GetIteratorToNode( groupNode );

  if (treeIter->IsAtEnd()) treeIter->GoToBegin();

  treeIter->Add(node); // insert below the group node

  // TODO synchronize some properties... (?)
    // synchronize color?    optional?
    // synchronize visibility?
  RenderingManager::GetInstance()->RequestUpdateAll(true); // including vtk actors
}

DataTreeNode* SegmentationSink::GetGroupNode()
{
  DataTreeNode::Pointer groupNode;
  GetPointerParameter("Group node", groupNode);

  return groupNode.GetPointer();
}

DataTreeNode* SegmentationSink::LookForPointerTargetBelowGroupNode(const char* name)
{
  DataTreeNode::Pointer groupNode;
  GetPointerParameter("Group node", groupNode);

  DataTree::Pointer dataTree;
  GetPointerParameter("Data tree", dataTree );

  if (groupNode.IsNotNull() && dataTree.IsNotNull())
  {
    DataTreeIteratorClone treeIter = dataTree->GetIteratorToNode( groupNode );

    SmartPointerProperty* spp = dynamic_cast<SmartPointerProperty*>( groupNode->GetProperty(name));

    if (spp) // try to find this node as a child
    {
      DataTreeNode* lookedForChildNode = dynamic_cast<DataTreeNode*>( spp->GetSmartPointer().GetPointer() );

      if (lookedForChildNode)
      {
        int position = treeIter->ChildPosition( lookedForChildNode );
        if ( position != -1 )
        {
          treeIter->GoToChild( position );
          return treeIter->Get();
        }
      }

    }
  }

  return NULL;

}

} // namespace

<commit_msg>FIX (#1172): Some algorithms put results to DataTree, not DataStorage<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkSegmentationSink.h"
#include "mitkRenderingManager.h"
#include "mitkDataStorage.h"

namespace mitk {

SegmentationSink::SegmentationSink()
{
}

SegmentationSink::~SegmentationSink()
{
}

void SegmentationSink::Initialize(const NonBlockingAlgorithm* other)
{
  Superclass::Initialize(other);
  // sinks should be called explicitly from the tool, because otherwise the order of setting "Input" and "Group node" would matter
  UnDefineTriggerParameter("Input");

  // some basedata output
  DataTreeNode::Pointer groupNode;
  bool showResult(true);

  if (other)
  {
    other->GetPointerParameter("Group node", groupNode);
    other->GetParameter("Show result", showResult);
  }

  SetPointerParameter("Group node", groupNode );
  SetParameter("Show result", showResult );
}

bool SegmentationSink::ReadyToRun()
{
  Image::Pointer image;
  GetPointerParameter("Input", image);

  DataTreeNode::Pointer groupNode;
  GetPointerParameter("Group node", groupNode);

  return image.IsNotNull() && groupNode.IsNotNull();
}

bool SegmentationSink::ThreadedUpdateFunction()
{
  return true;
}

/// to be called by subclasses when they want to insert some resulting object (binary image, surface, ...) into the data tree
void SegmentationSink::InsertBelowGroupNode(mitk::DataTreeNode* node)
{
  DataTreeNode* groupNode = GetGroupNode();

  DataStorage::GetInstance()->Add( node, groupNode );

  RenderingManager::GetInstance()->RequestUpdateAll(true); // including vtk actors
}

DataTreeNode* SegmentationSink::GetGroupNode()
{
  DataTreeNode::Pointer groupNode;
  GetPointerParameter("Group node", groupNode);

  return groupNode.GetPointer();
}

DataTreeNode* SegmentationSink::LookForPointerTargetBelowGroupNode(const char* name)
{
  DataTreeNode::Pointer groupNode;
  GetPointerParameter("Group node", groupNode);

  if (groupNode.IsNotNull())
  {
    return DataStorage::GetInstance()->GetNamedDerivedNode(name, groupNode, true);
  }

  return NULL;

}

} // namespace

<|endoftext|>


<commit_before>#include <curses.h>
#include <ctime>

#include "version.h"
#ifndef VERSION_STRING
	#define VERSION_STRING "unknown"
#endif

#include "common.hh"
#include "console.hh"
#include "actor.hh"
#include "world.hh"
#include "screens.hh"

bool handleInput(Actor& pl) {
	int k = getch();

	if (!pl.possessing || pl.possession()) {
		if      (k == KEY_ESCAPE || k == 'q') return false;
		else if (k == KEY_LEFT   || k == '4') pl.move(-1,0);
		else if (k == KEY_RIGHT  || k == '6') pl.move(1,0);
		else if (k == KEY_UP     || k == '8') pl.move(0,-1);
		else if (k == KEY_DOWN   || k == '2') pl.move(0,1);
		else if (k == '7') pl.move(-1,-1);
		else if (k == '9') pl.move( 1,-1);
		else if (k == '1') pl.move(-1, 1);
		else if (k == '3') pl.move( 1, 1);
		else if (k == '5') pl.idle();
		else if (k == '?' || k == 'h' || k == KEY_F(1)) { help(); frame(pl); }
		// Abilities
		else if (ability_keys.find(k) != std::string::npos) {
			size_t i = 0;
			// Find the ability
			for (Abilities::iterator it = pl.abilities.begin();
			  it != pl.abilities.end() && i < ability_keys.length(); ++it) {
				if (it->hidden || it->automatic) continue; // Only explicitly usable skills have a key
				if (ability_keys[i] == k) {
					(*it)(&pl); break; // Do action
				}
				i++;
			}
		}

		// Cheats
		else if (k == KEY_F(4)) pl.viewDist = 100;
		else if (k == KEY_F(5)) pl.type = Actor::HUMAN;
		else if (k == KEY_F(6)) pl.type = Actor::ANGEL;
		else if (k == KEY_F(7)) pl.type = Actor::DEMON;
		else if (k == KEY_F(8)) pl.addExp(1);
		else if (k == KEY_F(9)) pl.hurt(1);
	} else pl.msgs.push_back("The possessed soul revolts.");

	flushinp();
	if (pl.isDead()) return false;
	return true;
}

bool mainLoop() {

	int abc = title();
	if (abc == 0) return false; // Quit game

	boost::scoped_ptr<World> world(new World());
	Actor& pl(world->addActor(new Actor(abc == 1 ? Actor::ANGEL : Actor::IMP, NO_AI)));
	pl.position(abc == 1 ? world->getWidth()-3 : 2, world->getHeight() / 2);
	pl.abilities.push_back(newAbility(Ability_LookAt));

	// Actors
	Actor::Type actor_types[] = {
		Actor::HUMAN, Actor::HUMAN, Actor::HUMAN, Actor::HUMAN,
		Actor::HUMAN, Actor::HUMAN, Actor::HUMAN, Actor::HUMAN,
		Actor::HUMAN, Actor::HUMAN, Actor::HUMAN, Actor::HUMAN,
		Actor::HUMAN, Actor::IMP,   Actor::IMP,   Actor::IMP,
		Actor::IMP,   Actor::IMP,   Actor::DEMON, Actor::ANGEL
	};
	for (int i = 0; i < 150; i++) {
		Actor& a(world->addActor(new Actor(actor_types[randint(20)])));
		while (!a.position(randint(world->getWidth()),
		                   randint(world->getHeight())));
	}

	erase();
	frame(pl);
	refresh();

	do {
		frame(pl, true);
		refresh();
		world->update();
		world->draw(pl);
	} while(!pl.isDead() && handleInput(pl) && !winner(pl));
	if (pl.isDead()) death();

	return true; // Come back to main loop for the title screen
}

int main(int argc, char* argv[]) {
	// Process commandline
	if (argc > 1) {
		for (int i = 1; i < argc; ++i) {
			std::string arg(argv[i]);
			if (arg == "-v" || arg == "--version") {
				std::cout << "Version: " << VERSION_STRING << std::endl;
				exit(0);
			} else if (arg == "-h" || arg == "--help") {
				std::cout << "Usage: " << argv[0] << " [-v|--version] [-h|--help]" << std::endl;
				exit(0);
			} else {
				std::cout << "Unrecognized parameter: " << arg << std::endl;
				exit(-1);
			}
		}
	}

	srand(time(NULL)); // Randomize RNG

	{
		ConsoleWindow cons;
		while (mainLoop());
	}
	return 0;
}

<commit_msg>Move some key bindings out of possession detection.<commit_after>#include <curses.h>
#include <ctime>

#include "version.h"
#ifndef VERSION_STRING
	#define VERSION_STRING "unknown"
#endif

#include "common.hh"
#include "console.hh"
#include "actor.hh"
#include "world.hh"
#include "screens.hh"

bool handleInput(Actor& pl) {
	int k = getch();

	if      (k == KEY_ESCAPE || k == 'q') return false;
	else if (k == '?' || k == 'h' || k == KEY_F(1)) { help(); frame(pl); }

	else if (!pl.possessing || pl.possession()) {
		if (k == ' ' || k == '5') pl.idle();
		else if (k == KEY_LEFT   || k == '4') pl.move(-1,0);
		else if (k == KEY_RIGHT  || k == '6') pl.move(1,0);
		else if (k == KEY_UP     || k == '8') pl.move(0,-1);
		else if (k == KEY_DOWN   || k == '2') pl.move(0,1);
		else if (k == '7') pl.move(-1,-1);
		else if (k == '9') pl.move( 1,-1);
		else if (k == '1') pl.move(-1, 1);
		else if (k == '3') pl.move( 1, 1);
		// Abilities
		else if (ability_keys.find(k) != std::string::npos) {
			size_t i = 0;
			// Find the ability
			for (Abilities::iterator it = pl.abilities.begin();
			  it != pl.abilities.end() && i < ability_keys.length(); ++it) {
				if (it->hidden || it->automatic) continue; // Only explicitly usable skills have a key
				if (ability_keys[i] == k) {
					(*it)(&pl); break; // Do action
				}
				i++;
			}
		}

		// Cheats
		else if (k == KEY_F(4)) pl.viewDist = 100;
		else if (k == KEY_F(5)) pl.type = Actor::HUMAN;
		else if (k == KEY_F(6)) pl.type = Actor::ANGEL;
		else if (k == KEY_F(7)) pl.type = Actor::DEMON;
		else if (k == KEY_F(8)) pl.addExp(1);
		else if (k == KEY_F(9)) pl.hurt(1);
	} else pl.msgs.push_back("The possessed soul revolts.");

	flushinp();
	if (pl.isDead()) return false;
	return true;
}

bool mainLoop() {

	int abc = title();
	if (abc == 0) return false; // Quit game

	boost::scoped_ptr<World> world(new World());
	Actor& pl(world->addActor(new Actor(abc == 1 ? Actor::ANGEL : Actor::IMP, NO_AI)));
	pl.position(abc == 1 ? world->getWidth()-3 : 2, world->getHeight() / 2);
	pl.abilities.push_back(newAbility(Ability_LookAt));

	// Actors
	Actor::Type actor_types[] = {
		Actor::HUMAN, Actor::HUMAN, Actor::HUMAN, Actor::HUMAN,
		Actor::HUMAN, Actor::HUMAN, Actor::HUMAN, Actor::HUMAN,
		Actor::HUMAN, Actor::HUMAN, Actor::HUMAN, Actor::HUMAN,
		Actor::HUMAN, Actor::IMP,   Actor::IMP,   Actor::IMP,
		Actor::IMP,   Actor::IMP,   Actor::DEMON, Actor::ANGEL
	};
	for (int i = 0; i < 150; i++) {
		Actor& a(world->addActor(new Actor(actor_types[randint(20)])));
		while (!a.position(randint(world->getWidth()),
		                   randint(world->getHeight())));
	}

	erase();
	frame(pl);
	refresh();

	do {
		frame(pl, true);
		refresh();
		world->update();
		world->draw(pl);
	} while(!pl.isDead() && handleInput(pl) && !winner(pl));
	if (pl.isDead()) death();

	return true; // Come back to main loop for the title screen
}

int main(int argc, char* argv[]) {
	// Process commandline
	if (argc > 1) {
		for (int i = 1; i < argc; ++i) {
			std::string arg(argv[i]);
			if (arg == "-v" || arg == "--version") {
				std::cout << "Version: " << VERSION_STRING << std::endl;
				exit(0);
			} else if (arg == "-h" || arg == "--help") {
				std::cout << "Usage: " << argv[0] << " [-v|--version] [-h|--help]" << std::endl;
				exit(0);
			} else {
				std::cout << "Unrecognized parameter: " << arg << std::endl;
				exit(-1);
			}
		}
	}

	srand(time(NULL)); // Randomize RNG

	{
		ConsoleWindow cons;
		while (mainLoop());
	}
	return 0;
}

<|endoftext|>


<commit_before>// @file main.cc
// @brief Morse code generator
// @author Mamoru Kaminaga
// @date 2016-05-15 12:08:31
// Copyright 2016 Mamoru Kaminaga
#include <wchar.h>
#include <windows.h>
#include <stdio.h>
#include "common.h"
#include "morse_player.h"
#include "resource.h"
#include "sound_device.h"
#define WINDOW_STYLE    (WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX)
enum OPTIONS {
  OPTION_HELP = 0,
  OPTION_STRING,
  OPTION_NOWINDOW,
  OPTION_NOSOUND,
  OPTION_WPM,
  OPTION_PARIS,
  ELEMNUM_OPTIONS, // Array size.
};
const wchar_t kOptions[ELEMNUM_OPTIONS][16] = {
  L"-help",        // OPTION_HELP
  L"-s",           // OPTION_STRING
  L"-nowindow",    // OPTION_NOWINDOW
  L"-nosound",     // OPTION_NOSOUND
  L"-wpm",         // OPTION_WPM
  L"-paris",       // OPTION_PARIS
};
const wchar_t kHelp[ELEMNUM_OPTIONS][64] = {
  L"Show help",                        // OPTION_HELP
  L"Input string to be morse signal",  // OPTION_STRING
  L"Not show output console",          // OPTION_NOWINDOW
  L"Not play midi sound",              // OPTION_NOSOUND
  L"Set WPM, default is 20",           // OPTION_WPM
  L"Set PARIS, default is 20",         // OPTION_PARIS
};
bool help_required = false;
bool no_console = false;
bool no_sound = false;
bool play_command_line_string = false;
int string_argc_offset = 0;
namespace mk {
void ShowAndPlay(MorsePlayer* morse_player, wchar_t charactor) {
  int morse_code = 0;
  switch (charactor) {
    case L'a': case L'A': morse_code = MORSE_A; break;
    case L'b': case L'B': morse_code = MORSE_B; break;
    case L'c': case L'C': morse_code = MORSE_C; break;
    case L'd': case L'D': morse_code = MORSE_D; break;
    case L'e': case L'E': morse_code = MORSE_E; break;
    case L'f': case L'F': morse_code = MORSE_F; break;
    case L'g': case L'G': morse_code = MORSE_G; break;
    case L'h': case L'H': morse_code = MORSE_H; break;
    case L'i': case L'I': morse_code = MORSE_I; break;
    case L'j': case L'J': morse_code = MORSE_J; break;
    case L'k': case L'K': morse_code = MORSE_K; break;
    case L'l': case L'L': morse_code = MORSE_L; break;
    case L'm': case L'M': morse_code = MORSE_M; break;
    case L'n': case L'N': morse_code = MORSE_N; break;
    case L'o': case L'O': morse_code = MORSE_O; break;
    case L'p': case L'P': morse_code = MORSE_P; break;
    case L'q': case L'Q': morse_code = MORSE_Q; break;
    case L'r': case L'R': morse_code = MORSE_R; break;
    case L's': case L'S': morse_code = MORSE_S; break;
    case L't': case L'T': morse_code = MORSE_T; break;
    case L'u': case L'U': morse_code = MORSE_U; break;
    case L'v': case L'V': morse_code = MORSE_V; break;
    case L'w': case L'W': morse_code = MORSE_W; break;
    case L'x': case L'X': morse_code = MORSE_X; break;
    case L'y': case L'Y': morse_code = MORSE_Y; break;
    case L'z': case L'Z': morse_code = MORSE_Z; break;
    case L'1': morse_code = MORSE_1; break;
    case L'2': morse_code = MORSE_2; break;
    case L'3': morse_code = MORSE_3; break;
    case L'4': morse_code = MORSE_4; break;
    case L'5': morse_code = MORSE_5; break;
    case L'6': morse_code = MORSE_6; break;
    case L'7': morse_code = MORSE_7; break;
    case L'8': morse_code = MORSE_8; break;
    case L'9': morse_code = MORSE_9; break;
    case L'0': morse_code = MORSE_0; break;
    case L'.': morse_code = MORSE_PER; break;
    case L',': morse_code = MORSE_COM; break;
    case L'?': morse_code = MORSE_QUE; break;
    case L'-': morse_code = MORSE_HIF; break;
    case L'/': morse_code = MORSE_SLA; break;
    case L'@': morse_code = MORSE_ATM; break;
    case L' ': morse_code = MORSE_SPACE; break;
    default: morse_code = MORSE_UNKNOWN; break;
  }
  // Morse shown to console.
  if (!no_console) morse_player->ShowSimbol(morse_code);
  // Sound played by device.
  if (!no_sound) morse_player->PlaySound(morse_code);
}
// Void callback function.
LRESULT CALLBACK WndProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) {
  // Prevent warnings for unreferenced parameters.
  UNREFERENCED_PARAMETER(wnd);
  UNREFERENCED_PARAMETER(wp);
  UNREFERENCED_PARAMETER(lp);
  switch (msg) {
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      break;
  }
  return DefWindowProc(wnd, msg, wp, lp);
}
// Window is required to set icom on win32 application.
HWND CreateInvisibleWindow(HINSTANCE instance_handle) {
  WNDCLASSEX wcex;
  // Window class registered.
  memset(&wcex, 0, sizeof(wcex));
  wcex.cbSize = sizeof(wcex);
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = WndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = instance_handle;
  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wcex.lpszMenuName = NULL;
  wcex.lpszClassName = APP_NAME;
  wcex.hIcon = LoadIcon(instance_handle, MAKEINTRESOURCE(IDI_ICON1));
  wcex.hIconSm = LoadIcon(instance_handle, MAKEINTRESOURCE(IDI_ICON1));
  if (RegisterClassEx(&wcex) == 0) return false;
  // Invisible window created.
  return CreateWindow(APP_NAME, APP_NAME, WINDOW_STYLE, CW_USEDEFAULT,
                      CW_USEDEFAULT, 256, 256, NULL, NULL, instance_handle,
                      NULL);
}
}  // namespace mk
int WINAPI wWinMain(HINSTANCE instance_handle, HINSTANCE not_used,
                    LPTSTR cmd_lind, int cmd_show) {
  // Prevent warnings for unreferenced parameters.
  UNREFERENCED_PARAMETER(instance_handle);
  UNREFERENCED_PARAMETER(not_used);
  UNREFERENCED_PARAMETER(cmd_lind);
  UNREFERENCED_PARAMETER(cmd_show);
  //
  HWND window_handle = mk::CreateInvisibleWindow(instance_handle);
  mk::SoundDevice device(window_handle);
  device.Initialize();
  mk::MorsePlayer morse_player(&device);
  morse_player.Initialize();
  morse_player.dot_ms_ = 60;
  // Command line args proc.
  for (int i = 1; i < __argc; ++i) {
    for (int j = 0; j < ELEMNUM_OPTIONS; ++j) {
      if (wcscmp(__wargv[i], kOptions[j]) == 0) {
        switch (j) {
          case OPTION_HELP:
            help_required = true;
            break;
          case OPTION_NOWINDOW:
            no_console = true;
            break;
          case OPTION_NOSOUND:
            no_sound = true;
            break;
          case OPTION_WPM:  // Same as OPTION_PARIS
          case OPTION_PARIS:
            // wpm (paris) -> dot millis
            morse_player.dot_ms_ = 60000 / (_wtoi(__wargv[i + 1]) * 50);
            break;
          case OPTION_STRING:
            play_command_line_string = true;
            string_argc_offset = i + 1;
          default:
            break;
        }
      }
    }
  }
  // Console proc.
  if (!no_console) {
    if (!AttachConsole(ATTACH_PARENT_PROCESS)) AllocConsole();
    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
  }
  // Argument num error check proc.
  if (__argc <= 1) {
    if (no_console) {
      mk::DialogError(L"No arguments specified");
      return -1;
    } else {
      mk::PrintError(L"No arguments specified");
      goto ERROR_EXIT;
    }
  }
  // Help option proc.
  if (help_required) {
    if (no_console) {
      mk::DialogError(L"You must not set -nowindow option to show help");
      return 0;
    } else {
      wprintf(APP_NAME);
      wprintf(L"\n");
      wprintf(L"options:\n");
      for (int i = 0; i < ELEMNUM_OPTIONS; ++i) {
        wprintf(L"%s:\t%s\n", kOptions[i], kHelp[i]);
      }
      goto ERROR_EXIT;
    }
  }
  // String error proc.
  if (play_command_line_string == false) {
    if (no_console) {
      mk::DialogError(L"No input string");
      return -1;
    } else {
      mk::PrintError(L"No input string");
      goto ERROR_EXIT;
    }
  }
  // Morse generation proc.
  int length = 0;
  for (int i = string_argc_offset; i < __argc; ++i) {
    length = wcslen(__wargv[i]);
    for (int j = 0; j < length; ++j) {
      mk::ShowAndPlay(&morse_player, __wargv[i][j]);
      mk::ShowAndPlay(&morse_player, L' ');
    }
    if (i != (__argc - 1)) {  // Word separator.
      mk::ShowAndPlay(&morse_player, L' ');
      mk::ShowAndPlay(&morse_player, L' ');
      mk::ShowAndPlay(&morse_player, L' ');
    }
  }
  // Normal exit proc.
  if (!no_console) {
    system("PAUSE");
    FreeConsole();
  }
  morse_player.Finalize();
  device.Finalize();
  return 0;

ERROR_EXIT:
  // Error exit proc.
  if (!no_console) {
    system("PAUSE");
    FreeConsole();
  }
  morse_player.Finalize();
  device.Finalize();
  return -1;
}
<commit_msg>Return charactor to consale before PAUSE<commit_after>// @file main.cc
// @brief Morse code generator
// @author Mamoru Kaminaga
// @date 2016-05-15 12:08:31
// Copyright 2016 Mamoru Kaminaga
#include <wchar.h>
#include <windows.h>
#include <stdio.h>
#include "common.h"
#include "morse_player.h"
#include "resource.h"
#include "sound_device.h"
#define WINDOW_STYLE    (WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX)
enum OPTIONS {
  OPTION_HELP = 0,
  OPTION_STRING,
  OPTION_NOWINDOW,
  OPTION_NOSOUND,
  OPTION_WPM,
  OPTION_PARIS,
  ELEMNUM_OPTIONS, // Array size.
};
const wchar_t kOptions[ELEMNUM_OPTIONS][16] = {
  L"-help",        // OPTION_HELP
  L"-s",           // OPTION_STRING
  L"-nowindow",    // OPTION_NOWINDOW
  L"-nosound",     // OPTION_NOSOUND
  L"-wpm",         // OPTION_WPM
  L"-paris",       // OPTION_PARIS
};
const wchar_t kHelp[ELEMNUM_OPTIONS][64] = {
  L"Show help",                        // OPTION_HELP
  L"Input string to be morse signal",  // OPTION_STRING
  L"Not show output console",          // OPTION_NOWINDOW
  L"Not play midi sound",              // OPTION_NOSOUND
  L"Set WPM, default is 20",           // OPTION_WPM
  L"Set PARIS, default is 20",         // OPTION_PARIS
};
bool help_required = false;
bool no_console = false;
bool no_sound = false;
bool play_command_line_string = false;
int string_argc_offset = 0;
namespace mk {
void ShowAndPlay(MorsePlayer* morse_player, wchar_t charactor) {
  int morse_code = 0;
  switch (charactor) {
    case L'a': case L'A': morse_code = MORSE_A; break;
    case L'b': case L'B': morse_code = MORSE_B; break;
    case L'c': case L'C': morse_code = MORSE_C; break;
    case L'd': case L'D': morse_code = MORSE_D; break;
    case L'e': case L'E': morse_code = MORSE_E; break;
    case L'f': case L'F': morse_code = MORSE_F; break;
    case L'g': case L'G': morse_code = MORSE_G; break;
    case L'h': case L'H': morse_code = MORSE_H; break;
    case L'i': case L'I': morse_code = MORSE_I; break;
    case L'j': case L'J': morse_code = MORSE_J; break;
    case L'k': case L'K': morse_code = MORSE_K; break;
    case L'l': case L'L': morse_code = MORSE_L; break;
    case L'm': case L'M': morse_code = MORSE_M; break;
    case L'n': case L'N': morse_code = MORSE_N; break;
    case L'o': case L'O': morse_code = MORSE_O; break;
    case L'p': case L'P': morse_code = MORSE_P; break;
    case L'q': case L'Q': morse_code = MORSE_Q; break;
    case L'r': case L'R': morse_code = MORSE_R; break;
    case L's': case L'S': morse_code = MORSE_S; break;
    case L't': case L'T': morse_code = MORSE_T; break;
    case L'u': case L'U': morse_code = MORSE_U; break;
    case L'v': case L'V': morse_code = MORSE_V; break;
    case L'w': case L'W': morse_code = MORSE_W; break;
    case L'x': case L'X': morse_code = MORSE_X; break;
    case L'y': case L'Y': morse_code = MORSE_Y; break;
    case L'z': case L'Z': morse_code = MORSE_Z; break;
    case L'1': morse_code = MORSE_1; break;
    case L'2': morse_code = MORSE_2; break;
    case L'3': morse_code = MORSE_3; break;
    case L'4': morse_code = MORSE_4; break;
    case L'5': morse_code = MORSE_5; break;
    case L'6': morse_code = MORSE_6; break;
    case L'7': morse_code = MORSE_7; break;
    case L'8': morse_code = MORSE_8; break;
    case L'9': morse_code = MORSE_9; break;
    case L'0': morse_code = MORSE_0; break;
    case L'.': morse_code = MORSE_PER; break;
    case L',': morse_code = MORSE_COM; break;
    case L'?': morse_code = MORSE_QUE; break;
    case L'-': morse_code = MORSE_HIF; break;
    case L'/': morse_code = MORSE_SLA; break;
    case L'@': morse_code = MORSE_ATM; break;
    case L' ': morse_code = MORSE_SPACE; break;
    default: morse_code = MORSE_UNKNOWN; break;
  }
  // Morse shown to console.
  if (!no_console) morse_player->ShowSimbol(morse_code);
  // Sound played by device.
  if (!no_sound) morse_player->PlaySound(morse_code);
}
// Void callback function.
LRESULT CALLBACK WndProc(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) {
  // Prevent warnings for unreferenced parameters.
  UNREFERENCED_PARAMETER(wnd);
  UNREFERENCED_PARAMETER(wp);
  UNREFERENCED_PARAMETER(lp);
  switch (msg) {
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    default:
      break;
  }
  return DefWindowProc(wnd, msg, wp, lp);
}
// Window is required to set icom on win32 application.
HWND CreateInvisibleWindow(HINSTANCE instance_handle) {
  WNDCLASSEX wcex;
  // Window class registered.
  memset(&wcex, 0, sizeof(wcex));
  wcex.cbSize = sizeof(wcex);
  wcex.style = CS_HREDRAW | CS_VREDRAW;
  wcex.lpfnWndProc = WndProc;
  wcex.cbClsExtra = 0;
  wcex.cbWndExtra = 0;
  wcex.hInstance = instance_handle;
  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  wcex.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  wcex.lpszMenuName = NULL;
  wcex.lpszClassName = APP_NAME;
  wcex.hIcon = LoadIcon(instance_handle, MAKEINTRESOURCE(IDI_ICON1));
  wcex.hIconSm = LoadIcon(instance_handle, MAKEINTRESOURCE(IDI_ICON1));
  if (RegisterClassEx(&wcex) == 0) return false;
  // Invisible window created.
  return CreateWindow(APP_NAME, APP_NAME, WINDOW_STYLE, CW_USEDEFAULT,
                      CW_USEDEFAULT, 256, 256, NULL, NULL, instance_handle,
                      NULL);
}
}  // namespace mk
int WINAPI wWinMain(HINSTANCE instance_handle, HINSTANCE not_used,
                    LPTSTR cmd_lind, int cmd_show) {
  // Prevent warnings for unreferenced parameters.
  UNREFERENCED_PARAMETER(instance_handle);
  UNREFERENCED_PARAMETER(not_used);
  UNREFERENCED_PARAMETER(cmd_lind);
  UNREFERENCED_PARAMETER(cmd_show);
  //
  HWND window_handle = mk::CreateInvisibleWindow(instance_handle);
  mk::SoundDevice device(window_handle);
  device.Initialize();
  mk::MorsePlayer morse_player(&device);
  morse_player.Initialize();
  morse_player.dot_ms_ = 60;
  // Command line args proc.
  for (int i = 1; i < __argc; ++i) {
    for (int j = 0; j < ELEMNUM_OPTIONS; ++j) {
      if (wcscmp(__wargv[i], kOptions[j]) == 0) {
        switch (j) {
          case OPTION_HELP:
            help_required = true;
            break;
          case OPTION_NOWINDOW:
            no_console = true;
            break;
          case OPTION_NOSOUND:
            no_sound = true;
            break;
          case OPTION_WPM:  // Same as OPTION_PARIS
          case OPTION_PARIS:
            // wpm (paris) -> dot millis
            morse_player.dot_ms_ = 60000 / (_wtoi(__wargv[i + 1]) * 50);
            break;
          case OPTION_STRING:
            play_command_line_string = true;
            string_argc_offset = i + 1;
          default:
            break;
        }
      }
    }
  }
  // Console proc.
  if (!no_console) {
    if (!AttachConsole(ATTACH_PARENT_PROCESS)) AllocConsole();
    freopen("CON", "r", stdin);
    freopen("CON", "w", stdout);
  }
  // Argument num error check proc.
  if (__argc <= 1) {
    if (no_console) {
      mk::DialogError(L"No arguments specified");
      return -1;
    } else {
      mk::PrintError(L"No arguments specified");
      goto ERROR_EXIT;
    }
  }
  // Help option proc.
  if (help_required) {
    if (no_console) {
      mk::DialogError(L"You must not set -nowindow option to show help");
      return 0;
    } else {
      wprintf(APP_NAME);
      wprintf(L"\n");
      wprintf(L"options:\n");
      for (int i = 0; i < ELEMNUM_OPTIONS; ++i) {
        wprintf(L"%s:\t%s\n", kOptions[i], kHelp[i]);
      }
      goto ERROR_EXIT;
    }
  }
  // String error proc.
  if (play_command_line_string == false) {
    if (no_console) {
      mk::DialogError(L"No input string");
      return -1;
    } else {
      mk::PrintError(L"No input string");
      goto ERROR_EXIT;
    }
  }
  // Morse generation proc.
  int length = 0;
  for (int i = string_argc_offset; i < __argc; ++i) {
    length = wcslen(__wargv[i]);
    for (int j = 0; j < length; ++j) {
      mk::ShowAndPlay(&morse_player, __wargv[i][j]);
      mk::ShowAndPlay(&morse_player, L' ');
    }
    if (i != (__argc - 1)) {  // Word separator.
      mk::ShowAndPlay(&morse_player, L' ');
      mk::ShowAndPlay(&morse_player, L' ');
      mk::ShowAndPlay(&morse_player, L' ');
    }
  }
  // Normal exit proc.
  if (!no_console) {
    wprintf(L"\n");
    system("PAUSE");
    FreeConsole();
  }
  morse_player.Finalize();
  device.Finalize();
  return 0;

ERROR_EXIT:
  // Error exit proc.
  if (!no_console) {
    wprintf(L"\n");
    system("PAUSE");
    FreeConsole();
  }
  morse_player.Finalize();
  device.Finalize();
  return -1;
}
<|endoftext|>


<commit_before>/*
 * File: src/commonpp/thread/detail/Core.cpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2016 Thomas Sanchez.  All rights reserved.
 *
 */

#include "logger.hpp"
#include "Core.hpp"

namespace commonpp
{
namespace thread
{
namespace detail
{

Core::Core(hwloc_topology_t& topology, hwloc_obj_t core)
: topology_(topology)
, core_(core)
{}

hwloc_cpuset_t const& Core::cpuset() const
{
    return core_->cpuset;
}

bool Core::bind(std::thread& thread)
{
    auto cpuset = hwloc_bitmap_dup(core_->cpuset);
    hwloc_bitmap_singlify(cpuset);

    if (hwloc_set_thread_cpubind(topology_, thread.native_handle(), cpuset, 0))
    {
        auto error = errno;
        LOG(thread_logger, warning) << "Error setting thread affinity: "
                                    << strerror(error);
        return false;
    }

    return true;
}

bool Core::bind()
{
    auto cpuset = hwloc_bitmap_dup(core_->cpuset);
    hwloc_bitmap_singlify(cpuset);

    if (hwloc_set_cpubind(topology_, cpuset, 0))
    {
        auto error = errno;
        LOG(thread_logger, warning) << "Error setting thread affinity: "
                                    << strerror(error);
        return false;
    }

    return true;
}

} // namespace detail
} // namespace thread
} // namespace commonpp
<commit_msg>Add forgotten free<commit_after>/*
 * File: src/commonpp/thread/detail/Core.cpp
 * Part of commonpp.
 *
 * Distributed under the 2-clause BSD licence (See LICENCE.TXT file at the
 * project root).
 *
 * Copyright (c) 2016 Thomas Sanchez.  All rights reserved.
 *
 */

#include "logger.hpp"
#include "Core.hpp"

namespace commonpp
{
namespace thread
{
namespace detail
{

Core::Core(hwloc_topology_t& topology, hwloc_obj_t core)
: topology_(topology)
, core_(core)
{}

hwloc_cpuset_t const& Core::cpuset() const
{
    return core_->cpuset;
}

bool Core::bind(std::thread& thread)
{
    auto cpuset = hwloc_bitmap_dup(core_->cpuset);
    hwloc_bitmap_singlify(cpuset);

    if (hwloc_set_thread_cpubind(topology_, thread.native_handle(), cpuset, 0))
    {
        auto error = errno;
        LOG(thread_logger, warning) << "Error setting thread affinity: "
                                    << strerror(error);
        hwloc_bitmap_free(cpuset);
        return false;
    }

    hwloc_bitmap_free(cpuset);
    return true;
}

bool Core::bind()
{
    auto cpuset = hwloc_bitmap_dup(core_->cpuset);
    hwloc_bitmap_singlify(cpuset);

    if (hwloc_set_cpubind(topology_, cpuset, 0))
    {
        auto error = errno;
        LOG(thread_logger, warning) << "Error setting thread affinity: "
                                    << strerror(error);
        hwloc_bitmap_free(cpuset);
        return false;
    }

    hwloc_bitmap_free(cpuset);
    return true;
}

} // namespace detail
} // namespace thread
} // namespace commonpp
<|endoftext|>


<commit_before>//
//  MCMailProvider.cpp
//  mailcore2
//
//  Created by Robert Widmann on 4/28/13.
//  Copyright (c) 2013 MailCore. All rights reserved.
//

#include "MCMailProvider.h"
#include "MCNetService.h"
#include "MCIterator.h"
#include "MCJSON.h"

#include <regex.h>

using namespace mailcore;

void MailProvider::init()
{
    mIdentifier = NULL;
    mImapServices = new Array();
    mSmtpServices = new Array();
    mPopServices = new Array();
    mDomainMatch = new Array();
    mMxSet = new Set();
    mMailboxPaths = NULL;
}

MailProvider::MailProvider()
{
    init();
}

MailProvider::MailProvider(MailProvider * other)
{
    init();
    MC_SAFE_REPLACE_COPY(String, mIdentifier, other->mIdentifier);
    MC_SAFE_REPLACE_COPY(Array, mImapServices, other->mImapServices);
    MC_SAFE_REPLACE_COPY(Array, mSmtpServices, other->mSmtpServices);
    MC_SAFE_REPLACE_COPY(Array, mPopServices, other->mPopServices);
    MC_SAFE_REPLACE_COPY(Array, mDomainMatch, other->mDomainMatch);
    MC_SAFE_REPLACE_COPY(Set, mMxSet, other->mMxSet);
    MC_SAFE_REPLACE_COPY(HashMap, mMailboxPaths, other->mMailboxPaths);
}

MailProvider::~MailProvider()
{
    MC_SAFE_RELEASE(mImapServices);
    MC_SAFE_RELEASE(mSmtpServices);
    MC_SAFE_RELEASE(mPopServices);
    MC_SAFE_RELEASE(mMxSet);
    MC_SAFE_RELEASE(mDomainMatch);
    MC_SAFE_RELEASE(mMailboxPaths);
    MC_SAFE_RELEASE(mIdentifier);
}

MailProvider * MailProvider::providerWithInfo(HashMap * info)
{
    MailProvider * provider = new MailProvider();
    provider->fillWithInfo(info);
    provider->autorelease();
    return provider;
}

void MailProvider::fillWithInfo(HashMap * info)
{
    Array * imapInfos;
    Array * smtpInfos;
    Array * popInfos;
    HashMap * serverInfo;
    Array * mxs;

    MC_SAFE_RELEASE(mDomainMatch);
    if (info->objectForKey(MCSTR("domain-match")) != NULL) {
        mDomainMatch = (Array *) info->objectForKey(MCSTR("domain-match"))->retain();
    }
    MC_SAFE_RELEASE(mMailboxPaths);
    if (info->objectForKey(MCSTR("mailboxes")) != NULL) {
        mMailboxPaths = (HashMap *) info->objectForKey(MCSTR("mailboxes"))->retain();
    }
    mxs = (Array *) info->objectForKey(MCSTR("mx"));
    mMxSet->removeAllObjects();
    mc_foreacharray(String, mx, mxs) {
        mMxSet->addObject(mx->lowercaseString());
    }

    serverInfo = (HashMap *) info->objectForKey(MCSTR("servers"));
    imapInfos = (Array *) serverInfo->objectForKey(MCSTR("imap"));
    smtpInfos = (Array *) serverInfo->objectForKey(MCSTR("smtp"));
    popInfos = (Array *) serverInfo->objectForKey(MCSTR("pop"));

    mImapServices->removeAllObjects();
    mc_foreacharray(HashMap, imapInfo, imapInfos) {
        NetService * service = NetService::serviceWithInfo(imapInfo);
        mImapServices->addObject(service);
    }

    mSmtpServices->removeAllObjects();
    mc_foreacharray(HashMap, smtpInfo, smtpInfos) {
        NetService * service = NetService::serviceWithInfo(smtpInfo);
        mSmtpServices->addObject(service);
    }

    mPopServices->removeAllObjects();
    mc_foreacharray(HashMap, popInfo, popInfos) {
        NetService * service = NetService::serviceWithInfo(popInfo);
        mPopServices->addObject(service);
    }
}

void MailProvider::setIdentifier(String * identifier)
{
    MC_SAFE_REPLACE_COPY(String, mIdentifier, identifier);
}

String * MailProvider::identifier()
{
    return mIdentifier;
}

Array * MailProvider::imapServices()
{
    return mImapServices;
}

Array * MailProvider::smtpServices()
{
    return mSmtpServices;
}

Array * MailProvider::popServices()
{
    return mPopServices;
}

bool MailProvider::matchEmail(String * email)
{
    Array * components;
    String * domain;
    const char * cDomain;

    components = email->componentsSeparatedByString(MCSTR("@"));
    if (components->count() < 2)
        return false;

    domain = (String *) components->lastObject();
    cDomain = domain->UTF8Characters();

    mc_foreacharray(String, match, mDomainMatch) {
        regex_t r;
        bool matched;

        match = String::stringWithUTF8Format("^%s$", match->UTF8Characters());
        if (regcomp(&r, match->UTF8Characters(), REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
            continue;

        matched = false;
        if (regexec(&r, cDomain, 0, NULL, 0) == 0) {
            matched = true;
        }

        regfree(&r);

        if (matched)
            return true;
    }

    return false;
}

bool MailProvider::matchMX(String * hostname)
{
    return mMxSet->containsObject(hostname->lowercaseString());
}

String * MailProvider::sentMailFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("sentmail"));
}

String * MailProvider::starredFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("starred"));
}

String * MailProvider::allMailFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("allmail"));
}

String * MailProvider::trashFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("trash"));
}

String * MailProvider::draftsFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("drafts"));
}

String * MailProvider::spamFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("spam"));
}

String * MailProvider::importantFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("important"));
}

bool MailProvider::isMainFolder(String * folderPath, String * prefix)
{
    mc_foreachhashmapValue(String, path, mMailboxPaths) {
        String * fullPath;

        if (prefix != NULL) {
            fullPath = prefix->stringByAppendingString((String *) path);
        }
        else {
            fullPath = path;
        }

        if (fullPath->isEqual(folderPath))
            return true;
    }

    return false;
}

String * MailProvider::description()
{
    return String::stringWithUTF8Format("<%s:%p, %s>", className()->UTF8Characters(), this, MCUTF8(mIdentifier));
}

Object * MailProvider::copy()
{
    return new MailProvider(this);
}

<commit_msg>Added assert in provider parser<commit_after>//
//  MCMailProvider.cpp
//  mailcore2
//
//  Created by Robert Widmann on 4/28/13.
//  Copyright (c) 2013 MailCore. All rights reserved.
//

#include "MCMailProvider.h"
#include "MCNetService.h"
#include "MCIterator.h"
#include "MCJSON.h"

#include <regex.h>

using namespace mailcore;

void MailProvider::init()
{
    mIdentifier = NULL;
    mImapServices = new Array();
    mSmtpServices = new Array();
    mPopServices = new Array();
    mDomainMatch = new Array();
    mMxSet = new Set();
    mMailboxPaths = NULL;
}

MailProvider::MailProvider()
{
    init();
}

MailProvider::MailProvider(MailProvider * other)
{
    init();
    MC_SAFE_REPLACE_COPY(String, mIdentifier, other->mIdentifier);
    MC_SAFE_REPLACE_COPY(Array, mImapServices, other->mImapServices);
    MC_SAFE_REPLACE_COPY(Array, mSmtpServices, other->mSmtpServices);
    MC_SAFE_REPLACE_COPY(Array, mPopServices, other->mPopServices);
    MC_SAFE_REPLACE_COPY(Array, mDomainMatch, other->mDomainMatch);
    MC_SAFE_REPLACE_COPY(Set, mMxSet, other->mMxSet);
    MC_SAFE_REPLACE_COPY(HashMap, mMailboxPaths, other->mMailboxPaths);
}

MailProvider::~MailProvider()
{
    MC_SAFE_RELEASE(mImapServices);
    MC_SAFE_RELEASE(mSmtpServices);
    MC_SAFE_RELEASE(mPopServices);
    MC_SAFE_RELEASE(mMxSet);
    MC_SAFE_RELEASE(mDomainMatch);
    MC_SAFE_RELEASE(mMailboxPaths);
    MC_SAFE_RELEASE(mIdentifier);
}

MailProvider * MailProvider::providerWithInfo(HashMap * info)
{
    MailProvider * provider = new MailProvider();
    provider->fillWithInfo(info);
    provider->autorelease();
    return provider;
}

void MailProvider::fillWithInfo(HashMap * info)
{
    Array * imapInfos;
    Array * smtpInfos;
    Array * popInfos;
    HashMap * serverInfo;
    Array * mxs;

    MC_SAFE_RELEASE(mDomainMatch);
    if (info->objectForKey(MCSTR("domain-match")) != NULL) {
        mDomainMatch = (Array *) info->objectForKey(MCSTR("domain-match"))->retain();
    }
    MC_SAFE_RELEASE(mMailboxPaths);
    if (info->objectForKey(MCSTR("mailboxes")) != NULL) {
        mMailboxPaths = (HashMap *) info->objectForKey(MCSTR("mailboxes"))->retain();
    }
    mxs = (Array *) info->objectForKey(MCSTR("mx"));
    mMxSet->removeAllObjects();
    mc_foreacharray(String, mx, mxs) {
        mMxSet->addObject(mx->lowercaseString());
    }

    serverInfo = (HashMap *) info->objectForKey(MCSTR("servers"));
    if (serverInfo == NULL) {
        MCLog("servers key missing from provider %s", MCUTF8DESC(info));
    }
    MCAssert(serverInfo != NULL);
    imapInfos = (Array *) serverInfo->objectForKey(MCSTR("imap"));
    smtpInfos = (Array *) serverInfo->objectForKey(MCSTR("smtp"));
    popInfos = (Array *) serverInfo->objectForKey(MCSTR("pop"));

    mImapServices->removeAllObjects();
    mc_foreacharray(HashMap, imapInfo, imapInfos) {
        NetService * service = NetService::serviceWithInfo(imapInfo);
        mImapServices->addObject(service);
    }

    mSmtpServices->removeAllObjects();
    mc_foreacharray(HashMap, smtpInfo, smtpInfos) {
        NetService * service = NetService::serviceWithInfo(smtpInfo);
        mSmtpServices->addObject(service);
    }

    mPopServices->removeAllObjects();
    mc_foreacharray(HashMap, popInfo, popInfos) {
        NetService * service = NetService::serviceWithInfo(popInfo);
        mPopServices->addObject(service);
    }
}

void MailProvider::setIdentifier(String * identifier)
{
    MC_SAFE_REPLACE_COPY(String, mIdentifier, identifier);
}

String * MailProvider::identifier()
{
    return mIdentifier;
}

Array * MailProvider::imapServices()
{
    return mImapServices;
}

Array * MailProvider::smtpServices()
{
    return mSmtpServices;
}

Array * MailProvider::popServices()
{
    return mPopServices;
}

bool MailProvider::matchEmail(String * email)
{
    Array * components;
    String * domain;
    const char * cDomain;

    components = email->componentsSeparatedByString(MCSTR("@"));
    if (components->count() < 2)
        return false;

    domain = (String *) components->lastObject();
    cDomain = domain->UTF8Characters();

    mc_foreacharray(String, match, mDomainMatch) {
        regex_t r;
        bool matched;

        match = String::stringWithUTF8Format("^%s$", match->UTF8Characters());
        if (regcomp(&r, match->UTF8Characters(), REG_EXTENDED | REG_ICASE | REG_NOSUB) != 0)
            continue;

        matched = false;
        if (regexec(&r, cDomain, 0, NULL, 0) == 0) {
            matched = true;
        }

        regfree(&r);

        if (matched)
            return true;
    }

    return false;
}

bool MailProvider::matchMX(String * hostname)
{
    return mMxSet->containsObject(hostname->lowercaseString());
}

String * MailProvider::sentMailFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("sentmail"));
}

String * MailProvider::starredFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("starred"));
}

String * MailProvider::allMailFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("allmail"));
}

String * MailProvider::trashFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("trash"));
}

String * MailProvider::draftsFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("drafts"));
}

String * MailProvider::spamFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("spam"));
}

String * MailProvider::importantFolderPath()
{
    return (String *) mMailboxPaths->objectForKey(MCSTR("important"));
}

bool MailProvider::isMainFolder(String * folderPath, String * prefix)
{
    mc_foreachhashmapValue(String, path, mMailboxPaths) {
        String * fullPath;

        if (prefix != NULL) {
            fullPath = prefix->stringByAppendingString((String *) path);
        }
        else {
            fullPath = path;
        }

        if (fullPath->isEqual(folderPath))
            return true;
    }

    return false;
}

String * MailProvider::description()
{
    return String::stringWithUTF8Format("<%s:%p, %s>", className()->UTF8Characters(), this, MCUTF8(mIdentifier));
}

Object * MailProvider::copy()
{
    return new MailProvider(this);
}

<|endoftext|>


<commit_before>#ifndef NOGTEST

/*
 * AuxGTest.cpp
 *
 *  Created on: 10.01.2013
 *      Author: Christian Staudt (christian.staudt@kit.edu)
 */

#include "AuxGTest.h"

#include <iostream>
#include <algorithm>
#include <chrono>
#include <thread>

#include "../Log.h"
#include "../Random.h"
#include "../Timer.h"
#include "../MissingMath.h"
#include "../PrioQueue.h"

TEST_F(AuxGTest, produceRandomIntegers) {
	int64_t l = 0; 	// lower bound
	int64_t u = 100;	// upper bound

	for (int i = 0; i < 100; ++i) {
		TRACE(Aux::Random::integer(l, u));
	}
}

TEST_F(AuxGTest, testRandomInteger) {
	int64_t l = 0; 	// lower bound
	int64_t u = 10;	// upper bound
	std::vector<int64_t> rVector;
	int n = 1000;
	for (int i = 0; i < n; ++i) {
		int64_t r = Aux::Random::integer(l, u);
		assert(l <= r);
		assert(r <= u);
		rVector.push_back(r);
	}

	int64_t minR = *(min_element(rVector.begin(), rVector.end()));
	int64_t maxR = *(max_element(rVector.begin(), rVector.end()));

	EXPECT_EQ(minR, l);
	EXPECT_EQ(maxR, u);

	double sum = std::accumulate(rVector.begin(), rVector.end(), uint64_t{0});
	double avg = sum / n;

	DEBUG("avg rand integer: ", avg);
	EXPECT_LE(avg, 6.0);
	EXPECT_GE(avg, 4.0);
}

TEST_F(AuxGTest, testRandomReal) {
	std::vector<double> rVector;
	int n = 1000;
	for (int i = 0; i < n; ++i) {
		double r = Aux::Random::real();
		assert(0.0 <= r);
		assert(r < 1.0);
		rVector.push_back(r);
	}

	double sum = std::accumulate(rVector.begin(), rVector.end(), 0.0);
	double avg = sum / n;

	DEBUG("avg rand probability: ", avg);
	EXPECT_LE(avg, 0.6);
	EXPECT_GE(avg, 0.4);
}

TEST_F(AuxGTest, testRandomProbability) {
	std::vector<double> rVector;
	int n = 1000;
	for (int i = 0; i < n; ++i) {
		double r = Aux::Random::probability();
		assert(0.0 <= r);
		assert(r <= 1.0);
		rVector.push_back(r);
	}

	double sum = std::accumulate(rVector.begin(), rVector.end(), 0.0);
	double avg = sum / n;

	DEBUG("avg rand probability: ", avg);
	EXPECT_LE(avg, 0.6);
	EXPECT_GE(avg, 0.4);
}

TEST_F(AuxGTest, testTimer) {
	int64_t sleepTime = 1000; // sleep time in ms
	int64_t tolerance = 20;

	Aux::Timer timer;
	DEBUG("sleeping for ", sleepTime, " ms");
	timer.start();
	std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
	timer.stop();
	std::chrono::duration<int64_t, std::milli> elapsed = timer.elapsed();
	int64_t ec = elapsed.count();

	EXPECT_LE(sleepTime - tolerance, ec) << "elapsed time should be roughly equal to sleep time";
	EXPECT_GE(sleepTime + tolerance, ec) << "elapsed time should be roughly to sleep time";
}

TEST_F(AuxGTest, testBinomial) {
	EXPECT_EQ(1, Aux::MissingMath::binomial(7,0));
	EXPECT_EQ(7, Aux::MissingMath::binomial(7,1));
	EXPECT_EQ(21, Aux::MissingMath::binomial(7,2));
	EXPECT_EQ(35, Aux::MissingMath::binomial(7,3));
	EXPECT_EQ(35, Aux::MissingMath::binomial(7,4));
	EXPECT_EQ(21, Aux::MissingMath::binomial(7,5));
	EXPECT_EQ(7, Aux::MissingMath::binomial(7,6));
	EXPECT_EQ(1, Aux::MissingMath::binomial(7,7));

}

TEST_F(AuxGTest, benchmarkBinomial) {
	Aux::Timer timer;
	INFO("starting calculation");
	timer.start();

	int64_t n = 500;
	for (int64_t k = 0; k < n; ++k) {
		Aux::MissingMath::binomial(n, k);
	}

	timer.stop();

	INFO("calculation finished after ", timer.elapsedTag());

}

TEST_F(AuxGTest, testVectorDebug) {
	std::vector<int> vec(10, 42);
	INFO(vec);
}

TEST_F(AuxGTest, testPriorityQueue) {
	typedef std::pair<double, uint64_t> ElemType;

	// fill vector
	std::vector<ElemType> vec;
	vec.push_back(std::make_pair(0.5, 0));
	vec.push_back(std::make_pair(3.5, 1));
	vec.push_back(std::make_pair(4.5, 2));
	vec.push_back(std::make_pair(2.5, 3));
	vec.push_back(std::make_pair(0.75, 4));
	vec.push_back(std::make_pair(1.5, 5));
	vec.push_back(std::make_pair(8.5, 6));
	vec.push_back(std::make_pair(3.25, 7));
	vec.push_back(std::make_pair(4.75, 8));
	vec.push_back(std::make_pair(5.0, 9));
	vec.push_back(std::make_pair(11.5, 10));
	vec.push_back(std::make_pair(0.25, 11));

	// construct pq from vector
	Aux::PrioQueue<double, uint64_t> pq(vec);
	EXPECT_EQ(pq.size(), vec.size());

	ElemType elem = pq.extractMin();
	EXPECT_EQ(elem.first, 0.25);
	EXPECT_EQ(elem.second, 11);
	EXPECT_EQ(pq.size(), vec.size() - 1);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 0.5);
	EXPECT_EQ(elem.second, 0);
	EXPECT_EQ(pq.size(), vec.size() - 2);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 0.75);
	EXPECT_EQ(elem.second, 4);
	EXPECT_EQ(pq.size(), vec.size() - 3);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 1.5);
	EXPECT_EQ(elem.second, 5);
	EXPECT_EQ(pq.size(), vec.size() - 4);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 2.5);
	EXPECT_EQ(elem.second, 3);
	EXPECT_EQ(pq.size(), vec.size() - 5);
}

//FIXME make this working again
/*TEST_F(AuxGTest, testLogging) {
	std::string cl = Aux::currentLogLevel();
	//FATAL("FATAL ERROR");
	//ERROR("This may be here");
	Aux::setLoglevel("ERROR");
	//FATAL("fatal error"<<3<<2.f);
	//ERROR("normal error"<<3<<2.f);
	//WARN("just a warning"<<3<<2.f);
	//INFO("for the sake of information", 3, 2.f);
	//DEBUG("important debug outputs", 3, 2.f);
	//TRACE("trace", 3, 2.f);
	Aux::setLoglevel("INFO");
	EXPECT_EQ("INFO",Aux::currentLogLevel());
	//FATAL("fatal error", 3, 2.f);
	//ERROR("normal error", 3, 2.f);
	//WARN("just a warning", 3, 2.f);
	//INFO("for the sake of information", 3, 2.f);
	//DEBUG("important debug outputs", 3, 2.f);
	//TRACE("trace", 3, 2.f);
	Aux::setLoglevel("TRACE");
	EXPECT_EQ("TRACE",Aux::currentLogLevel());
	//FATAL("fatal error", 3, 2.f);
	//ERROR("normal error", 3, 2.f);
	//WARN("just a warning", 3, 2.f);
	//INFO("for the sake of information", 3, 2.f);
	//DEBUG("important debug outputs", 3, 2.f);
	//TRACE("trace", 3, 2.f);
	Aux::setLoglevel(cl);
}*/

TEST_F(AuxGTest, testRandomChoice) {
	std::vector<uint64_t> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	for (uint64_t i = 0; i < 1000; ++i) {
		std::ignore = Aux::Random::choice(data);
	}
}

TEST_F(AuxGTest, testRandomWeightedChoice) {
	std::vector<std::pair<uint64_t, double> > data = {{0, 1.0}, {1, 0.0}};
	for (uint64_t i = 0; i < 100; ++i) {
		auto element = Aux::Random::weightedChoice(data);
		EXPECT_EQ(0, element);
	}
}

#endif /*NOGTEST */
<commit_msg>Add Tests for Aux::Random::index() and Aux::StringTools::split()<commit_after>#ifndef NOGTEST

/*
 * AuxGTest.cpp
 *
 *  Created on: 10.01.2013
 *      Author: Christian Staudt (christian.staudt@kit.edu)
 */

#include "AuxGTest.h"

#include <iostream>
#include <algorithm>
#include <chrono>
#include <thread>

#include "../Log.h"
#include "../Random.h"
#include "../Timer.h"
#include "../MissingMath.h"
#include "../PrioQueue.h"
#include "../StringTools.h"

TEST_F(AuxGTest, produceRandomIntegers) {
	int64_t l = 0; 	// lower bound
	int64_t u = 100;	// upper bound

	for (int i = 0; i < 100; ++i) {
		TRACE(Aux::Random::integer(l, u));
	}
}

TEST_F(AuxGTest, testRandomInteger) {
	int64_t l = 0; 	// lower bound
	int64_t u = 10;	// upper bound
	std::vector<int64_t> rVector;
	int n = 1000;
	for (int i = 0; i < n; ++i) {
		int64_t r = Aux::Random::integer(l, u);
		assert(l <= r);
		assert(r <= u);
		rVector.push_back(r);
	}

	int64_t minR = *(min_element(rVector.begin(), rVector.end()));
	int64_t maxR = *(max_element(rVector.begin(), rVector.end()));

	EXPECT_EQ(minR, l);
	EXPECT_EQ(maxR, u);

	double sum = std::accumulate(rVector.begin(), rVector.end(), uint64_t{0});
	double avg = sum / n;

	DEBUG("avg rand integer: ", avg);
	EXPECT_LE(avg, 6.0);
	EXPECT_GE(avg, 4.0);
}

TEST_F(AuxGTest, testRandomReal) {
	std::vector<double> rVector;
	int n = 1000;
	for (int i = 0; i < n; ++i) {
		double r = Aux::Random::real();
		assert(0.0 <= r);
		assert(r < 1.0);
		rVector.push_back(r);
	}

	double sum = std::accumulate(rVector.begin(), rVector.end(), 0.0);
	double avg = sum / n;

	DEBUG("avg rand probability: ", avg);
	EXPECT_LE(avg, 0.6);
	EXPECT_GE(avg, 0.4);
}

TEST_F(AuxGTest, testRandomProbability) {
	std::vector<double> rVector;
	int n = 1000;
	for (int i = 0; i < n; ++i) {
		double r = Aux::Random::probability();
		assert(0.0 <= r);
		assert(r <= 1.0);
		rVector.push_back(r);
	}

	double sum = std::accumulate(rVector.begin(), rVector.end(), 0.0);
	double avg = sum / n;

	DEBUG("avg rand probability: ", avg);
	EXPECT_LE(avg, 0.6);
	EXPECT_GE(avg, 0.4);
}

TEST_F(AuxGTest, testTimer) {
	int64_t sleepTime = 1000; // sleep time in ms
	int64_t tolerance = 20;

	Aux::Timer timer;
	DEBUG("sleeping for ", sleepTime, " ms");
	timer.start();
	std::this_thread::sleep_for(std::chrono::milliseconds(sleepTime));
	timer.stop();
	std::chrono::duration<int64_t, std::milli> elapsed = timer.elapsed();
	int64_t ec = elapsed.count();

	EXPECT_LE(sleepTime - tolerance, ec) << "elapsed time should be roughly equal to sleep time";
	EXPECT_GE(sleepTime + tolerance, ec) << "elapsed time should be roughly to sleep time";
}

TEST_F(AuxGTest, testBinomial) {
	EXPECT_EQ(1, Aux::MissingMath::binomial(7,0));
	EXPECT_EQ(7, Aux::MissingMath::binomial(7,1));
	EXPECT_EQ(21, Aux::MissingMath::binomial(7,2));
	EXPECT_EQ(35, Aux::MissingMath::binomial(7,3));
	EXPECT_EQ(35, Aux::MissingMath::binomial(7,4));
	EXPECT_EQ(21, Aux::MissingMath::binomial(7,5));
	EXPECT_EQ(7, Aux::MissingMath::binomial(7,6));
	EXPECT_EQ(1, Aux::MissingMath::binomial(7,7));

}

TEST_F(AuxGTest, benchmarkBinomial) {
	Aux::Timer timer;
	INFO("starting calculation");
	timer.start();

	int64_t n = 500;
	for (int64_t k = 0; k < n; ++k) {
		Aux::MissingMath::binomial(n, k);
	}

	timer.stop();

	INFO("calculation finished after ", timer.elapsedTag());

}

TEST_F(AuxGTest, testVectorDebug) {
	std::vector<int> vec(10, 42);
	INFO(vec);
}

TEST_F(AuxGTest, testPriorityQueue) {
	typedef std::pair<double, uint64_t> ElemType;

	// fill vector
	std::vector<ElemType> vec;
	vec.push_back(std::make_pair(0.5, 0));
	vec.push_back(std::make_pair(3.5, 1));
	vec.push_back(std::make_pair(4.5, 2));
	vec.push_back(std::make_pair(2.5, 3));
	vec.push_back(std::make_pair(0.75, 4));
	vec.push_back(std::make_pair(1.5, 5));
	vec.push_back(std::make_pair(8.5, 6));
	vec.push_back(std::make_pair(3.25, 7));
	vec.push_back(std::make_pair(4.75, 8));
	vec.push_back(std::make_pair(5.0, 9));
	vec.push_back(std::make_pair(11.5, 10));
	vec.push_back(std::make_pair(0.25, 11));

	// construct pq from vector
	Aux::PrioQueue<double, uint64_t> pq(vec);
	EXPECT_EQ(pq.size(), vec.size());

	ElemType elem = pq.extractMin();
	EXPECT_EQ(elem.first, 0.25);
	EXPECT_EQ(elem.second, 11);
	EXPECT_EQ(pq.size(), vec.size() - 1);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 0.5);
	EXPECT_EQ(elem.second, 0);
	EXPECT_EQ(pq.size(), vec.size() - 2);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 0.75);
	EXPECT_EQ(elem.second, 4);
	EXPECT_EQ(pq.size(), vec.size() - 3);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 1.5);
	EXPECT_EQ(elem.second, 5);
	EXPECT_EQ(pq.size(), vec.size() - 4);

	elem = pq.extractMin();
	EXPECT_EQ(elem.first, 2.5);
	EXPECT_EQ(elem.second, 3);
	EXPECT_EQ(pq.size(), vec.size() - 5);
}

//FIXME make this working again
/*TEST_F(AuxGTest, testLogging) {
	std::string cl = Aux::currentLogLevel();
	//FATAL("FATAL ERROR");
	//ERROR("This may be here");
	Aux::setLoglevel("ERROR");
	//FATAL("fatal error"<<3<<2.f);
	//ERROR("normal error"<<3<<2.f);
	//WARN("just a warning"<<3<<2.f);
	//INFO("for the sake of information", 3, 2.f);
	//DEBUG("important debug outputs", 3, 2.f);
	//TRACE("trace", 3, 2.f);
	Aux::setLoglevel("INFO");
	EXPECT_EQ("INFO",Aux::currentLogLevel());
	//FATAL("fatal error", 3, 2.f);
	//ERROR("normal error", 3, 2.f);
	//WARN("just a warning", 3, 2.f);
	//INFO("for the sake of information", 3, 2.f);
	//DEBUG("important debug outputs", 3, 2.f);
	//TRACE("trace", 3, 2.f);
	Aux::setLoglevel("TRACE");
	EXPECT_EQ("TRACE",Aux::currentLogLevel());
	//FATAL("fatal error", 3, 2.f);
	//ERROR("normal error", 3, 2.f);
	//WARN("just a warning", 3, 2.f);
	//INFO("for the sake of information", 3, 2.f);
	//DEBUG("important debug outputs", 3, 2.f);
	//TRACE("trace", 3, 2.f);
	Aux::setLoglevel(cl);
}*/

TEST_F(AuxGTest, testRandomChoice) {
	std::vector<uint64_t> data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	for (uint64_t i = 0; i < 1000; ++i) {
		std::ignore = Aux::Random::choice(data);
	}
}

TEST_F(AuxGTest, testRandomWeightedChoice) {
	std::vector<std::pair<uint64_t, double> > data = {{0, 1.0}, {1, 0.0}};
	for (uint64_t i = 0; i < 100; ++i) {
		auto element = Aux::Random::weightedChoice(data);
		EXPECT_EQ(0, element);
	}
}

TEST_F(AuxGTest, testRandomIndex) {
	using namespace Aux::Random;

	for(unsigned i = 0; i <10; ++i) {
		EXPECT_EQ(0, index(1));
	}

	for(unsigned i = 0; i <100; ++i) {
		auto tmp = index(10);
		EXPECT_LE(tmp, 9);
		EXPECT_GE(tmp, 0);
	}
}

TEST_F(AuxGTest, testSplit) {
	using Vec = std::vector<std::string>;
	using namespace Aux::StringTools;

	EXPECT_EQ(Vec{}, split(""));
	EXPECT_EQ(Vec{""}, split(" "));

	{
		auto expected = Vec{"", ""};
		EXPECT_EQ(expected, split("  "));
	}
	{
		auto expected = Vec{"", "a"};
		EXPECT_EQ(expected, split(" a"));
	}
	{
		auto expected = Vec{"a"};
		EXPECT_EQ(expected, split("a "));
	}
	{
		auto expected = Vec{"a"};
		EXPECT_EQ(expected, split("a"));
	}
	{
		auto expected = Vec{"a", "b"};
		EXPECT_EQ(expected, split("a b"));
	}
	{
		auto expected = Vec{"", "a", "b"};
		EXPECT_EQ(expected, split(" a b "));
	}
	{
		auto expected = Vec{"abc", "def", "ghi"};
		EXPECT_EQ(expected, split("abc def ghi"));
	}
	{
		auto expected = Vec{"abc", "def", "ghi"};
		EXPECT_EQ(expected, split("abc def ghi "));
	}
}

#endif /*NOGTEST */
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015-2016, Google Inc.
 * 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 Google Inc. 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
 * OWNER 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.
 *
 */
#include <grpc++/support/channel_arguments.h>

#include <sstream>

#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/log.h>
#include "src/core/channel/channel_args.h"

namespace grpc {

ChannelArguments::ChannelArguments() {
  std::ostringstream user_agent_prefix;
  user_agent_prefix << "grpc-c++/" << grpc_version_string();
  // This will be ignored if used on the server side.
  SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, user_agent_prefix.str());
}

ChannelArguments::ChannelArguments(const ChannelArguments& other)
    : strings_(other.strings_) {
  args_.reserve(other.args_.size());
  auto list_it_dst = strings_.begin();
  auto list_it_src = other.strings_.begin();
  for (auto a = other.args_.begin(); a != other.args_.end(); ++a) {
    grpc_arg ap;
    ap.type = a->type;
    GPR_ASSERT(list_it_src->c_str() == a->key);
    ap.key = const_cast<char*>(list_it_dst->c_str());
    ++list_it_src;
    ++list_it_dst;
    switch (a->type) {
      case GRPC_ARG_INTEGER:
        ap.value.integer = a->value.integer;
        break;
      case GRPC_ARG_STRING:
        GPR_ASSERT(list_it_src->c_str() == a->value.string);
        ap.value.string = const_cast<char*>(list_it_dst->c_str());
        ++list_it_src;
        ++list_it_dst;
        break;
      case GRPC_ARG_POINTER:
        ap.value.pointer = a->value.pointer;
        ap.value.pointer.p = a->value.pointer.copy
                                 ? a->value.pointer.copy(ap.value.pointer.p)
                                 : ap.value.pointer.p;
        break;
    }
    args_.push_back(ap);
  }
}

void ChannelArguments::Swap(ChannelArguments& other) {
  args_.swap(other.args_);
  strings_.swap(other.strings_);
}

void ChannelArguments::SetCompressionAlgorithm(
    grpc_compression_algorithm algorithm) {
  SetInt(GRPC_COMPRESSION_ALGORITHM_ARG, algorithm);
}

// Note: a second call to this will add in front the result of the first call.
void ChannelArguments::SetUserAgentPrefix(
    const grpc::string& user_agent_prefix) {
  if (user_agent_prefix.empty()) {
    return;
  }
  bool replaced = false;
  for (auto it = args_.begin(); it != args_.end(); ++it) {
    const grpc_arg& arg = *it;
    if (arg.type == GRPC_ARG_STRING &&
        grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
      strings_.push_back(user_agent_prefix + " " + arg.value.string);
      it->value.string = const_cast<char*>(strings_.back().c_str());
      replaced = true;
      break;
    }
  }
  if (!replaced) {
    SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, user_agent_prefix);
  }
}

void ChannelArguments::SetInt(const grpc::string& key, int value) {
  grpc_arg arg;
  arg.type = GRPC_ARG_INTEGER;
  strings_.push_back(key);
  arg.key = const_cast<char*>(strings_.back().c_str());
  arg.value.integer = value;

  args_.push_back(arg);
}

void ChannelArguments::SetPointer(const grpc::string& key, void* value) {
  grpc_arg arg;
  arg.type = GRPC_ARG_POINTER;
  strings_.push_back(key);
  arg.key = const_cast<char*>(strings_.back().c_str());
  arg.value.pointer.p = value;
  arg.value.pointer.copy = nullptr;
  arg.value.pointer.destroy = nullptr;
  args_.push_back(arg);
}

void ChannelArguments::SetString(const grpc::string& key,
                                 const grpc::string& value) {
  grpc_arg arg;
  arg.type = GRPC_ARG_STRING;
  strings_.push_back(key);
  arg.key = const_cast<char*>(strings_.back().c_str());
  strings_.push_back(value);
  arg.value.string = const_cast<char*>(strings_.back().c_str());

  args_.push_back(arg);
}

void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const {
  channel_args->num_args = args_.size();
  if (channel_args->num_args > 0) {
    channel_args->args = const_cast<grpc_arg*>(&args_[0]);
  }
}

}  // namespace grpc
<commit_msg>add comments<commit_after>/*
 *
 * Copyright 2015-2016, Google Inc.
 * 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 Google Inc. 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
 * OWNER 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.
 *
 */
#include <grpc++/support/channel_arguments.h>

#include <sstream>

#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/log.h>
#include "src/core/channel/channel_args.h"

namespace grpc {

ChannelArguments::ChannelArguments() {
  std::ostringstream user_agent_prefix;
  user_agent_prefix << "grpc-c++/" << grpc_version_string();
  // This will be ignored if used on the server side.
  SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, user_agent_prefix.str());
}

ChannelArguments::ChannelArguments(const ChannelArguments& other)
    : strings_(other.strings_) {
  args_.reserve(other.args_.size());
  auto list_it_dst = strings_.begin();
  auto list_it_src = other.strings_.begin();
  for (auto a = other.args_.begin(); a != other.args_.end(); ++a) {
    grpc_arg ap;
    ap.type = a->type;
    GPR_ASSERT(list_it_src->c_str() == a->key);
    ap.key = const_cast<char*>(list_it_dst->c_str());
    ++list_it_src;
    ++list_it_dst;
    switch (a->type) {
      case GRPC_ARG_INTEGER:
        ap.value.integer = a->value.integer;
        break;
      case GRPC_ARG_STRING:
        GPR_ASSERT(list_it_src->c_str() == a->value.string);
        ap.value.string = const_cast<char*>(list_it_dst->c_str());
        ++list_it_src;
        ++list_it_dst;
        break;
      case GRPC_ARG_POINTER:
        ap.value.pointer = a->value.pointer;
        ap.value.pointer.p = a->value.pointer.copy
                                 ? a->value.pointer.copy(ap.value.pointer.p)
                                 : ap.value.pointer.p;
        break;
    }
    args_.push_back(ap);
  }
}

void ChannelArguments::Swap(ChannelArguments& other) {
  args_.swap(other.args_);
  strings_.swap(other.strings_);
}

void ChannelArguments::SetCompressionAlgorithm(
    grpc_compression_algorithm algorithm) {
  SetInt(GRPC_COMPRESSION_ALGORITHM_ARG, algorithm);
}

// Note: a second call to this will add in front the result of the first call.
// An example is calling this on a copy of ChannelArguments which already has a
// prefix. The user can build up a prefix string by calling this multiple times,
// each with more significant identifier.
void ChannelArguments::SetUserAgentPrefix(
    const grpc::string& user_agent_prefix) {
  if (user_agent_prefix.empty()) {
    return;
  }
  bool replaced = false;
  for (auto it = args_.begin(); it != args_.end(); ++it) {
    const grpc_arg& arg = *it;
    if (arg.type == GRPC_ARG_STRING &&
        grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
      strings_.push_back(user_agent_prefix + " " + arg.value.string);
      it->value.string = const_cast<char*>(strings_.back().c_str());
      replaced = true;
      break;
    }
  }
  if (!replaced) {
    SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, user_agent_prefix);
  }
}

void ChannelArguments::SetInt(const grpc::string& key, int value) {
  grpc_arg arg;
  arg.type = GRPC_ARG_INTEGER;
  strings_.push_back(key);
  arg.key = const_cast<char*>(strings_.back().c_str());
  arg.value.integer = value;

  args_.push_back(arg);
}

void ChannelArguments::SetPointer(const grpc::string& key, void* value) {
  grpc_arg arg;
  arg.type = GRPC_ARG_POINTER;
  strings_.push_back(key);
  arg.key = const_cast<char*>(strings_.back().c_str());
  arg.value.pointer.p = value;
  arg.value.pointer.copy = nullptr;
  arg.value.pointer.destroy = nullptr;
  args_.push_back(arg);
}

void ChannelArguments::SetString(const grpc::string& key,
                                 const grpc::string& value) {
  grpc_arg arg;
  arg.type = GRPC_ARG_STRING;
  strings_.push_back(key);
  arg.key = const_cast<char*>(strings_.back().c_str());
  strings_.push_back(value);
  arg.value.string = const_cast<char*>(strings_.back().c_str());

  args_.push_back(arg);
}

void ChannelArguments::SetChannelArgs(grpc_channel_args* channel_args) const {
  channel_args->num_args = args_.size();
  if (channel_args->num_args > 0) {
    channel_args->args = const_cast<grpc_arg*>(&args_[0]);
  }
}

}  // namespace grpc
<|endoftext|>


<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include "DiscovererWorker.h"

#include "logging/Logger.h"
#include "MediaLibrary.h"

namespace medialibrary
{

DiscovererWorker::DiscovererWorker( MediaLibraryPtr ml )
    : m_run( false )
    , m_cb( ml->getCb() )
{
}

DiscovererWorker::~DiscovererWorker()
{
    stop();
}

void DiscovererWorker::addDiscoverer( std::unique_ptr<IDiscoverer> discoverer )
{
    m_discoverers.push_back( std::move( discoverer ) );
}

void DiscovererWorker::stop()
{
    bool running = true;
    if ( m_run.compare_exchange_strong( running, false ) )
    {
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            while ( m_tasks.empty() == false )
                m_tasks.pop();
        }
        m_cond.notify_all();
        m_thread.join();
    }
}

bool DiscovererWorker::discover( const std::string& entryPoint )
{
    if ( entryPoint.length() == 0 )
        return false;
    enqueue( entryPoint, false );
    return true;
}

void DiscovererWorker::reload()
{
    enqueue( "", true );
}

void DiscovererWorker::reload( const std::string& entryPoint )
{
    enqueue( entryPoint, true );
}

void DiscovererWorker::enqueue( const std::string& entryPoint, bool reload )
{
    std::unique_lock<compat::Mutex> lock( m_mutex );

    m_tasks.emplace( entryPoint, reload );
    if ( m_thread.get_id() == compat::Thread::id{} )
    {
        m_run = true;
        m_thread = compat::Thread( &DiscovererWorker::run, this );
    }
    // Since we just added an element, let's not check for size == 0 :)
    else if ( m_tasks.size() == 1 )
        m_cond.notify_all();
}

void DiscovererWorker::run()
{
    LOG_INFO( "Entering DiscovererWorker thread" );
    while ( m_run == true )
    {
        Task task;
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            if ( m_tasks.size() == 0 )
            {
                m_cond.wait( lock, [this]() { return m_tasks.size() > 0 || m_run == false; } );
                if ( m_run == false )
                    break;
            }
            task = m_tasks.front();
            m_tasks.pop();
        }
        m_cb->onDiscoveryStarted( task.entryPoint );
        if ( task.reload == false )
        {
            for ( auto& d : m_discoverers )
            {
                // Assume only one discoverer can handle an entrypoint.
                try
                {
                    if ( d->discover( task.entryPoint ) == true )
                        break;
                }
                catch(std::exception& ex)
                {
                    LOG_ERROR( "Fatal error while discovering ", task.entryPoint, ": ", ex.what() );
                }

                if ( m_run == false )
                    break;
            }
        }
        else
        {
            for ( auto& d : m_discoverers )
            {
                try
                {
                    if ( task.entryPoint.empty() == true )
                        d->reload();
                    else
                        d->reload( task.entryPoint );
                }
                catch(std::exception& ex)
                {
                    LOG_ERROR( "Fatal error while reloading: ", ex.what() );
                }
                if ( m_run == false )
                    break;
            }
        }
        m_cb->onDiscoveryCompleted( task.entryPoint );
    }
    LOG_INFO( "Exiting DiscovererWorker thread" );
}

}
<commit_msg>discoverer: Log when adding a folder to the discovery list<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#if HAVE_CONFIG_H
# include "config.h"
#endif

#include "DiscovererWorker.h"

#include "logging/Logger.h"
#include "MediaLibrary.h"

namespace medialibrary
{

DiscovererWorker::DiscovererWorker( MediaLibraryPtr ml )
    : m_run( false )
    , m_cb( ml->getCb() )
{
}

DiscovererWorker::~DiscovererWorker()
{
    stop();
}

void DiscovererWorker::addDiscoverer( std::unique_ptr<IDiscoverer> discoverer )
{
    m_discoverers.push_back( std::move( discoverer ) );
}

void DiscovererWorker::stop()
{
    bool running = true;
    if ( m_run.compare_exchange_strong( running, false ) )
    {
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            while ( m_tasks.empty() == false )
                m_tasks.pop();
        }
        m_cond.notify_all();
        m_thread.join();
    }
}

bool DiscovererWorker::discover( const std::string& entryPoint )
{
    if ( entryPoint.length() == 0 )
        return false;
    LOG_INFO( "Adding ", entryPoint, " to the folder discovery list" );
    enqueue( entryPoint, false );
    return true;
}

void DiscovererWorker::reload()
{
    enqueue( "", true );
}

void DiscovererWorker::reload( const std::string& entryPoint )
{
    enqueue( entryPoint, true );
}

void DiscovererWorker::enqueue( const std::string& entryPoint, bool reload )
{
    std::unique_lock<compat::Mutex> lock( m_mutex );

    m_tasks.emplace( entryPoint, reload );
    if ( m_thread.get_id() == compat::Thread::id{} )
    {
        m_run = true;
        m_thread = compat::Thread( &DiscovererWorker::run, this );
    }
    // Since we just added an element, let's not check for size == 0 :)
    else if ( m_tasks.size() == 1 )
        m_cond.notify_all();
}

void DiscovererWorker::run()
{
    LOG_INFO( "Entering DiscovererWorker thread" );
    while ( m_run == true )
    {
        Task task;
        {
            std::unique_lock<compat::Mutex> lock( m_mutex );
            if ( m_tasks.size() == 0 )
            {
                m_cond.wait( lock, [this]() { return m_tasks.size() > 0 || m_run == false; } );
                if ( m_run == false )
                    break;
            }
            task = m_tasks.front();
            m_tasks.pop();
        }
        m_cb->onDiscoveryStarted( task.entryPoint );
        if ( task.reload == false )
        {
            for ( auto& d : m_discoverers )
            {
                // Assume only one discoverer can handle an entrypoint.
                try
                {
                    if ( d->discover( task.entryPoint ) == true )
                        break;
                }
                catch(std::exception& ex)
                {
                    LOG_ERROR( "Fatal error while discovering ", task.entryPoint, ": ", ex.what() );
                }

                if ( m_run == false )
                    break;
            }
        }
        else
        {
            for ( auto& d : m_discoverers )
            {
                try
                {
                    if ( task.entryPoint.empty() == true )
                        d->reload();
                    else
                        d->reload( task.entryPoint );
                }
                catch(std::exception& ex)
                {
                    LOG_ERROR( "Fatal error while reloading: ", ex.what() );
                }
                if ( m_run == false )
                    break;
            }
        }
        m_cb->onDiscoveryCompleted( task.entryPoint );
    }
    LOG_INFO( "Exiting DiscovererWorker thread" );
}

}
<|endoftext|>