<commit_before>#include <iostream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/stat.h>
#include <vector>

using namespace std;
int info_RF(char* dirName);
int info_D(char* dirName);
int info_CS(char* dirName);
int info_BS(char* dirName);
int info_S(char* dirName);
int info_SL(char* dirName);
int info_R(char* dirName);
int info_W(char* dirName);
int info_X(char* dirName);
int main()
{
	char *word[50];
    char buf[500] = "\0";
    int i, k=0;
	cin.getline(buf, 500);

    word[k] = strtok(buf, " ");

    while (word[k++] != NULL) {
        word[k] = strtok(NULL, " ");
    }
 	char checking_first = *word[0];
/*	pid_t pid;
	pid = fork();
	if(pid == 0)
	{
		if(k<=3  && word[0] != "exit"){
			string cmd("./src./single_command.sh ");
			cmd += word[0];
			cmd += " ";
			cmd += word[1];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for single_command.sh
		else if(checking_first == '#'){
			string cmd("./src./comment_command.sh ");
			system(cmd.c_str());		//run for comment_command.sh
			perror("invalid input");
		}
		else if(word[0] == "exit"){
			string cmd("./src./exit.sh ");
			cmd += word[0];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for exit.sh
		else	{
			int initial = 0;
			int hold_number = 0;
			int hold_other_number = 0;
			int ret[20];
			int v[20];

			while(initial <= k){
			string cmd("./src./multi_command.sh ");
				if(word[initial] == "|"|| word[initial] == "&" || word[initial][strlen(word[initial]-1)] == ';'){
					if(hold_number < initial){
						while(hold_number <initial){
						cmd += word[hold_number];
						hold_number++;
						}
						ret[hold_other_number] = system(cmd.c_str());
						v[hold_other_number] = WEXITSTATUS(ret[hold_other_number]);
					}
				}
				initial++;
			}
		}
		int status = 0;
		waitpid(pid, status, WNOHANG);
		if(status != 1){
			perror("fail to close child process");
		}

	}
	else if(pid == -1){
		cout<<"fork error!"<<endl;
	}
	else{
		cout<<"Should not be in parents"<<endl;
	}
*/
//top of part is for homework 01 which does not working so i made it as comment
	cout<<"program is passing through get cin"<<endl;
		if(checking_first == '[' || word[0] =="test"){
				cout<<"program is passing through checking_first == [ or test "<<endl;
			checking_first = *word[1];
			if(checking_first == '-'){
				cout<<"program is passing through '-' "<<endl;
				//All functions need that file exist
					vector<char *> dirlist;
					dirlist.push_back(word[2]);
					if(word[1] == "-a" || word[1] == "-e"){ //True if <file> exist
						cout<<"file exist"<<endl;
					}
					else if(word[1] == "-f"){//True if <file> exist and is regular file
						if(info_RF(dirlist.front()) == 1){
						cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-d"){//True if <file> exist and is a directory
						if(info_D(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-c"){//True if <file> exist and is character special file
						if(info_CS(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-b"){//True if <file> exist and is block special file
						if(info_BS(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-p"){//True if <file> exist and is named pipe
						// need to
					}
					else if(word[1] == "-S"){//True if <file> exist and is socket file
						if(info_S(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-L" || word[1] =="-h"){//True if <file> exist and is symbolic link
						if(info_SL(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-g"){//True if <file> exist and is sgid bit set
						// need to
					}
					else if(word[1] == "-u"){//True if <file> exist and is suid bit set
						// need to
					}
					else if(word[1] == "-r"){//True if <file> exist and is readable
						if(info_R(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-w"){//True if <file> exist and is writeable
						if(info_W(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-x"){//True if <file> exist and is excutable
						if(info_X(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-s"){//True if <file> exist and size of file is bigger than 0 (not empty)
						//need to
					}
					else if(word[1] == "-t"){//True if file descriptor <fd> is open and refers to a terminal
						//need to
					}
			}
			checking_first = *word[2];
			if(checking_first == '-'){ // there is two files to compare
				if(word[2] == "-nt"){// True if <file1> is newer than <file2>

				}
				else if(word[2] == "-ot"){// True if <file1> is older than <file2>

				}
				else if(word[2] == "-ef"){// True if <file1> and <file2> refer to the same device and inode numbers.

				}
			}
		}
	return 0;
}
int info_RF(char* dirName){//regular file
	struct stat sb;
	if((sb.st_mode & S_IFREG)){
		return 1;
	}
	return 0;
}
int info_D(char* dirName){
	struct stat sb;
	if((sb.st_mode & S_IFDIR)){
		return 1;
	}
	return 0;
}
int info_CS(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFCHR)){
		return 1;
	}
	return 0;
}
int info_BS(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFBLK)){
		return 1;
	}
	return 0;
}
int info_S(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFSOCK)){
		return 1;
	}
	return 0;
}
int info_SL(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFLNK)){
		return 1;
	}
	return 0;
}
 int info_R(char * dirName){//read
	 struct stat sb;
	 if((sb.st_mode & S_IRUSR)){
		return 1;
	 }
	 return 0;
 }
int info_W(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IWUSR)){
		return 1;
	}
	return 0;
}
int info_X(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IXUSR)){
		return 1;
	}
	return 0;
}<commit_msg>201511201818<commit_after>#include <iostream>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <math.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/stat.h>
#include <vector>

using namespace std;
int info_RF(char* dirName);
int info_D(char* dirName);
int info_CS(char* dirName);
int info_BS(char* dirName);
int info_S(char* dirName);
int info_SL(char* dirName);
int info_R(char* dirName);
int info_W(char* dirName);
int info_X(char* dirName);
int main()
{
	char *word[50];
    char buf[500] = "\0";
    int i, k=0;
	cin.getline(buf, 500);

    word[k] = strtok(buf, " ");

    while (word[k++] != NULL) {
        word[k] = strtok(NULL, " ");
    }
 	char checking_first = word[0];
/*	pid_t pid;
	pid = fork();
	if(pid == 0)
	{
		if(k<=3  && word[0] != "exit"){
			string cmd("./src./single_command.sh ");
			cmd += word[0];
			cmd += " ";
			cmd += word[1];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for single_command.sh
		else if(checking_first == '#'){
			string cmd("./src./comment_command.sh ");
			system(cmd.c_str());		//run for comment_command.sh
			perror("invalid input");
		}
		else if(word[0] == "exit"){
			string cmd("./src./exit.sh ");
			cmd += word[0];
			system(cmd.c_str());
			perror("invalid input");
		}								//run for exit.sh
		else	{
			int initial = 0;
			int hold_number = 0;
			int hold_other_number = 0;
			int ret[20];
			int v[20];

			while(initial <= k){
			string cmd("./src./multi_command.sh ");
				if(word[initial] == "|"|| word[initial] == "&" || word[initial][strlen(word[initial]-1)] == ';'){
					if(hold_number < initial){
						while(hold_number <initial){
						cmd += word[hold_number];
						hold_number++;
						}
						ret[hold_other_number] = system(cmd.c_str());
						v[hold_other_number] = WEXITSTATUS(ret[hold_other_number]);
					}
				}
				initial++;
			}
		}
		int status = 0;
		waitpid(pid, status, WNOHANG);
		if(status != 1){
			perror("fail to close child process");
		}

	}
	else if(pid == -1){
		cout<<"fork error!"<<endl;
	}
	else{
		cout<<"Should not be in parents"<<endl;
	}
*/
//top of part is for homework 01 which does not working so i made it as comment
	cout<<"program is passing through get cin"<<endl;
		if(checking_first == '[' || word[0] =="test"){
				cout<<"program is passing through checking_first == [ or test "<<endl;
			checking_first = word[1];
			if(checking_first == '-'){
				cout<<"program is passing through '-' "<<endl;
				//All functions need that file exist
					vector<char *> dirlist;
					dirlist.push_back(word[2]);
					if(word[1] == "-a" || word[1] == "-e"){ //True if <file> exist
						cout<<"file exist"<<endl;
					}
					else if(word[1] == "-f"){//True if <file> exist and is regular file
						if(info_RF(dirlist.front()) == 1){
						cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-d"){//True if <file> exist and is a directory
						if(info_D(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-c"){//True if <file> exist and is character special file
						if(info_CS(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-b"){//True if <file> exist and is block special file
						if(info_BS(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-p"){//True if <file> exist and is named pipe
						// need to
					}
					else if(word[1] == "-S"){//True if <file> exist and is socket file
						if(info_S(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-L" || word[1] =="-h"){//True if <file> exist and is symbolic link
						if(info_SL(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-g"){//True if <file> exist and is sgid bit set
						// need to
					}
					else if(word[1] == "-u"){//True if <file> exist and is suid bit set
						// need to
					}
					else if(word[1] == "-r"){//True if <file> exist and is readable
						if(info_R(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-w"){//True if <file> exist and is writeable
						if(info_W(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-x"){//True if <file> exist and is excutable
						if(info_X(dirlist.front()) == 1){
							cout<<"file exist"<<endl;
						}
						else
							cout<<"file does not exist"<<endl;
					}
					else if(word[1] == "-s"){//True if <file> exist and size of file is bigger than 0 (not empty)
						//need to
					}
					else if(word[1] == "-t"){//True if file descriptor <fd> is open and refers to a terminal
						//need to
					}
			}
			checking_first = *word[2];
			if(checking_first == '-'){ // there is two files to compare
				if(word[2] == "-nt"){// True if <file1> is newer than <file2>

				}
				else if(word[2] == "-ot"){// True if <file1> is older than <file2>

				}
				else if(word[2] == "-ef"){// True if <file1> and <file2> refer to the same device and inode numbers.

				}
			}
		}
	return 0;
}
int info_RF(char* dirName){//regular file
	struct stat sb;
	if((sb.st_mode & S_IFREG)){
		return 1;
	}
	return 0;
}
int info_D(char* dirName){
	struct stat sb;
	if((sb.st_mode & S_IFDIR)){
		return 1;
	}
	return 0;
}
int info_CS(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFCHR)){
		return 1;
	}
	return 0;
}
int info_BS(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFBLK)){
		return 1;
	}
	return 0;
}
int info_S(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFSOCK)){
		return 1;
	}
	return 0;
}
int info_SL(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IFLNK)){
		return 1;
	}
	return 0;
}
 int info_R(char * dirName){//read
	 struct stat sb;
	 if((sb.st_mode & S_IRUSR)){
		return 1;
	 }
	 return 0;
 }
int info_W(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IWUSR)){
		return 1;
	}
	return 0;
}
int info_X(char * dirName){
	struct stat sb;
	if((sb.st_mode & S_IXUSR)){
		return 1;
	}
	return 0;
}<|endoftext|>


<commit_before><commit_msg>Also check for libvorbisfile.dll and libvorbisidec.dll in Windows<commit_after><|endoftext|>


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

    FontAwesome.cpp
    Created: 13 Jul 2014 12:45:27pm
    Author:  Daniel Lindenfelser

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

#include "FontAwesome.h"

Typeface::Ptr FontAwesome_ptr = Typeface::createSystemTypefaceFor(
    FontAwesomeData::fontawesomewebfont_ttf,
    FontAwesomeData::fontawesomewebfont_ttfSize);
Font FontAwesome() {
  Font fontAwesomeFont(FontAwesome_ptr);
  return fontAwesomeFont;
}

Font getFontAwesome(float height) {
  Font fontAwesomeFont = FontAwesome();
  fontAwesomeFont.setHeight(height);
  return fontAwesomeFont;
}

void DrawIcon(Graphics &g, int x, int y, float height, String icon) {
  g.setFont(getFontAwesome(height));
  g.drawText(icon, (int)x, (int)y, (int)height, (int)height,
             Justification::centred, true);
}
<commit_msg>dirty fix Linux Font loading<commit_after>/*
  ==============================================================================

    FontAwesome.cpp
    Created: 13 Jul 2014 12:45:27pm
    Author:  Daniel Lindenfelser

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

#include "FontAwesome.h"

#if JUCE_LINUX
Font getFontAwesome(float height) {
  Font fontAwesomeFont("FontAwesome", height, Font::plain);
  return fontAwesomeFont;
}
#else
Typeface::Ptr FontAwesome_ptr = Typeface::createSystemTypefaceFor(
    FontAwesomeData::fontawesomewebfont_ttf,
    FontAwesomeData::fontawesomewebfont_ttfSize);
Font FontAwesome() {
  Font fontAwesomeFont(FontAwesome_ptr);
  return fontAwesomeFont;
}

Font getFontAwesome(float height) {
  Font fontAwesomeFont = FontAwesome();
  fontAwesomeFont.setHeight(height);
  return fontAwesomeFont;
}
#endif

void DrawIcon(Graphics &g, int x, int y, float height, String icon) {
  g.setFont(getFontAwesome(height));
  g.drawText(icon, (int)x, (int)y, (int)height, (int)height,
             Justification::centred, true);
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "QmitkDiffusionImagingAppWorkbenchAdvisor.h"

#include "internal/QmitkDiffusionApplicationPlugin.h"

#include <berryPlatform.h>
#include <berryIPreferencesService.h>
#include <berryWorkbenchPreferenceConstants.h>
#include <QmitkExtWorkbenchWindowAdvisor.h>

#include <QApplication>
#include <QPoint>
#include <QRect>
#include <QDesktopWidget>

const QString QmitkDiffusionImagingAppWorkbenchAdvisor::WELCOME_PERSPECTIVE_ID = "org.mitk.diffusionimagingapp.perspectives.welcome";

void
QmitkDiffusionImagingAppWorkbenchAdvisor::Initialize(berry::IWorkbenchConfigurer::Pointer configurer)
{
  berry::QtWorkbenchAdvisor::Initialize(configurer);

  configurer->SetSaveAndRestore(true);

}

berry::WorkbenchWindowAdvisor*
QmitkDiffusionImagingAppWorkbenchAdvisor::CreateWorkbenchWindowAdvisor(
    berry::IWorkbenchWindowConfigurer::Pointer configurer)
{
  QList<QString> perspExcludeList;
  perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective" );
  perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective2" );
  perspExcludeList.push_back("org.blueberry.perspectives.help");

  QList<QString> viewExcludeList;
  viewExcludeList.push_back( "org.mitk.views.controlvisualizationpropertiesview" );

  QRect rec = QApplication::desktop()->screenGeometry();
  configurer->SetInitialSize(QPoint(rec.width(),rec.height()));

  QmitkExtWorkbenchWindowAdvisor* advisor = new QmitkExtWorkbenchWindowAdvisor(this, configurer);
  advisor->ShowViewMenuItem(true);
  advisor->ShowNewWindowMenuItem(true);
  advisor->ShowClosePerspectiveMenuItem(true);
  advisor->SetPerspectiveExcludeList(perspExcludeList);
  advisor->SetViewExcludeList(viewExcludeList);
  advisor->ShowViewToolbar(false);
  advisor->ShowPerspectiveToolbar(true);
  advisor->ShowVersionInfo(true);
  advisor->ShowMitkVersionInfo(true);
  advisor->ShowMemoryIndicator(false);
  advisor->SetProductName("MITK Diffusion");
  advisor->SetWindowIcon(":/org.mitk.gui.qt.diffusionimagingapp/app-icon.png");
  return advisor;
}

QString QmitkDiffusionImagingAppWorkbenchAdvisor::GetInitialWindowPerspectiveId()
{
  return WELCOME_PERSPECTIVE_ID;
}
<commit_msg>intro is opened after display now<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

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

#include "QmitkDiffusionImagingAppWorkbenchAdvisor.h"

#include "internal/QmitkDiffusionApplicationPlugin.h"

#include <berryPlatform.h>
#include <berryIPreferencesService.h>
#include <berryWorkbenchPreferenceConstants.h>
#include <QmitkExtWorkbenchWindowAdvisor.h>

#include <QApplication>
#include <QPoint>
#include <QRect>
#include <QDesktopWidget>

const QString QmitkDiffusionImagingAppWorkbenchAdvisor::WELCOME_PERSPECTIVE_ID = "org.mitk.diffusionimagingapp.perspectives.welcome";

class QmitkDiffusionImagingAppWorkbenchWindowAdvisor : public QmitkExtWorkbenchWindowAdvisor
{

public:

  QmitkDiffusionImagingAppWorkbenchWindowAdvisor(berry::WorkbenchAdvisor* wbAdvisor,
                                                 berry::IWorkbenchWindowConfigurer::Pointer configurer)
    : QmitkExtWorkbenchWindowAdvisor(wbAdvisor, configurer)
  {

  }

  void PostWindowOpen()
  {
    QmitkExtWorkbenchWindowAdvisor::PostWindowOpen();
    berry::IWorkbenchWindowConfigurer::Pointer configurer = GetWindowConfigurer();
    configurer->GetWindow()->GetWorkbench()->GetIntroManager()->ShowIntro(configurer->GetWindow(), false);
  }

};

void
QmitkDiffusionImagingAppWorkbenchAdvisor::Initialize(berry::IWorkbenchConfigurer::Pointer configurer)
{
  berry::QtWorkbenchAdvisor::Initialize(configurer);

  configurer->SetSaveAndRestore(true);

}

berry::WorkbenchWindowAdvisor*
QmitkDiffusionImagingAppWorkbenchAdvisor::CreateWorkbenchWindowAdvisor(
    berry::IWorkbenchWindowConfigurer::Pointer configurer)
{
  QList<QString> perspExcludeList;
  perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective" );
  perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective2" );
  perspExcludeList.push_back("org.blueberry.perspectives.help");

  QList<QString> viewExcludeList;
  viewExcludeList.push_back( "org.mitk.views.controlvisualizationpropertiesview" );

  QRect rec = QApplication::desktop()->screenGeometry();
  configurer->SetInitialSize(QPoint(rec.width(),rec.height()));

  QmitkDiffusionImagingAppWorkbenchWindowAdvisor* advisor = new QmitkDiffusionImagingAppWorkbenchWindowAdvisor(this, configurer);
  advisor->ShowViewMenuItem(true);
  advisor->ShowNewWindowMenuItem(true);
  advisor->ShowClosePerspectiveMenuItem(true);
  advisor->SetPerspectiveExcludeList(perspExcludeList);
  advisor->SetViewExcludeList(viewExcludeList);
  advisor->ShowViewToolbar(false);
  advisor->ShowPerspectiveToolbar(true);
  advisor->ShowVersionInfo(true);
  advisor->ShowMitkVersionInfo(true);
  advisor->ShowMemoryIndicator(false);
  advisor->SetProductName("MITK Diffusion");
  advisor->SetWindowIcon(":/org.mitk.gui.qt.diffusionimagingapp/app-icon.png");
  return advisor;
}

QString QmitkDiffusionImagingAppWorkbenchAdvisor::GetInitialWindowPerspectiveId()
{
  return WELCOME_PERSPECTIVE_ID;
}
<|endoftext|>


<commit_before>#ifndef CLASS_PCI_NIC_HPP
#define CLASS_PCI_NIC_HPP

#include <class_pci_device.hpp>
#include <stdio.h>

// The nic knows about the IP stack
#include <net/class_ethernet.hpp>
#include <net/class_arp.hpp>
#include <net/class_ip4.hpp>
#include <net/class_ip6.hpp>

/*
class mac_t{
  unsigned char[6];
  const char* _str;

public:
  const char* c_str(){

  }
  }*/

class E1000{
public: const char* name(){ return "E1000 Driver"; };
};

class RTL8139;

/** A public interface for Network cards

  @todo(Alfred): We should probably inherit something here, but I still don't know what the common denominators are between a Nic and other devices, except that they should have a "name". When do we ever need/want to treat all devices similarly? I don't want to introduce vtables/polymorphism unless I know it's really useful. */
template<class DRIVER_T>
class Nic{

public:

  /** Get a readable name. @todo Replace the dummy with something useful.*/
  //const char* name();

  /** @note If we add this while there's a specialization, this overrides. */
  inline const char* name() { return driver.name(); };

  /** The actual mac address. */
  inline const mac_t& mac() { return driver.mac(); };

  /** Mac address string. */
  inline const char* mac_str() { return driver.mac_str(); };

    /** Event types */
    enum event_t {EthData, TCPConnection, TCPData,
                UDPConnection, UDPData, HttpRequest};

  /** Attach event handlers to Nic-events.

      @todo Decide between delegates and function pointers*/
  void on(event_t ev, void(*callback)());

private:
  Ethernet _eth;
  Arp _arp;
  IP4 _ip4;
  IP6 _ip6;

  DRIVER_T driver;

  /** Constructor.

      Just a wrapper around the driver constructor.
      @note The Dev-class is a friend and will call this */
  Nic(PCI_Device* d):
    _eth(),
    _arp(_eth),_ip4(_eth),_ip6(_eth),
    driver(d,_eth)
  {};

  friend class Dev;

};

//Driver instead? And delegate everything to it with a delegate?

/**
class Virtio_Nic :  public Nic /{

};

**/

#endif //Class Nic
<commit_msg>Cleanup<commit_after>#ifndef CLASS_PCI_NIC_HPP
#define CLASS_PCI_NIC_HPP

#include <class_pci_device.hpp>
#include <stdio.h>

// The nic knows about the IP stack
#include <net/class_ethernet.hpp>
#include <net/class_arp.hpp>
#include <net/class_ip4.hpp>
#include <net/class_ip6.hpp>

/** Future drivers may start out like so, */
class E1000{
public:
  const char* name(){ return "E1000 Driver"; }
  //...whatever the Nic class implicitly needs

};

/** Or so, etc.

    They'll have to provide anything the Nic class calls from them.
    @note{ There's no virtual interface, we'll need to call every function from
    he Nic class in order to make sure all members exist }
 */
class RTL8139;

/** A public interface for Network cards

    We're using compile-time polymorphism for now, so the "inheritance"
    requirements for a driver is implicily given by how it's used below,
    rather than explicitly by proper inheritance.
 */
template<class DRIVER_T>
class Nic{

public:

  /** Get a readable name. @todo Replace the dummy with something useful.*/
  //const char* name();

  /** @note If we add this while there's a specialization, this overrides. */
  inline const char* name() { return driver.name(); };

  /** The actual mac address. */
  inline const mac_t& mac() { return driver.mac(); };

  /** Mac address string. */
  inline const char* mac_str() { return driver.mac_str(); };

    /** Event types */
    enum event_t {EthData, TCPConnection, TCPData,
                UDPConnection, UDPData, HttpRequest};

  /** Attach event handlers to Nic-events.

      @todo Decide between delegates and function pointers*/
  void on(event_t ev, void(*callback)());

private:

  /** An IP stack (a skeleton for now).

      @todo We might consider adding the stack from the outside to save some
      overhead for services who only wants a few layers. (I.e. a bridge
      might not need the whole stack) */
  Ethernet _eth;
  Arp _arp;
  IP4 _ip4;
  IP6 _ip6;

  DRIVER_T driver;

  /** Constructor.

      Just a wrapper around the driver constructor.
      @note The Dev-class is a friend and will call this */
  Nic(PCI_Device* d):

    // Hook up the IP stack
    _eth(), _arp(_eth),_ip4(_eth),_ip6(_eth),

    // Add PCI and ethernet layer to the driver
    driver(d,_eth)
  {};

  friend class Dev;

};

#endif //Class Nic
<|endoftext|>


<commit_before>#include <Network/cUDPServerManager.h>
#include <Network/cUDPManager.h>
#include <Network/cDeliverManager.h>
#include <Network/cEventManager.h>
#include <Network/cRequestManager.h>
#include <Network/cResponseManager.h>
#include <cinder/app/App.h>
#include <limits>
#include <Node/action.hpp>
#include <Utility/MessageBox.h>
#include <Network/IpHost.h>
namespace Network
{
cUDPServerManager::cUDPServerManager( )
{
	closeAccepter( );
	mRoot = Node::node::create( );
	mRoot->set_schedule_update( );
}
void cUDPServerManager::close( )
{
    mRoot.reset( );
    mSocket.close( );
    closeAccepter( );
}
void cUDPServerManager::open( )
{
    mRoot = Node::node::create( );
    mRoot->set_schedule_update( );
    mSocket.open( 25565 );
    openAccepter( );
}
void cUDPServerManager::closeAccepter( )
{
	mIsAccept = false;
	mIdCount = 0;
	mConnections.clear( );
}
void cUDPServerManager::openAccepter( )
{
    mIsAccept = true;
}
void cUDPServerManager::update( float delta )
{
    updateRecv( );
    updateSend( );
    mRoot->entry_update( delta );
}
ubyte1 cUDPServerManager::getPlayerId( cNetworkHandle const & handle )
{
    auto itr = mConnections.find( handle );
    if ( itr != mConnections.end( ) )
    {
        return itr->second.id;
    }
    else
    {
        throw std::runtime_error( "Networkhandle nothing" );
    }
}
void cUDPServerManager::updateSend( )
{
    // M̂΃obt@[ođB
    for ( auto& client : mConnections )
    {
		auto& handle = client.first;
		auto& buf = client.second.buffer;

		// CAuȃf[^l߂܂B
		auto reliableData = client.second.reliableManager.update( );
		std::copy( reliableData.begin(), reliableData.end(), std::back_inserter( buf ) );

        // ]ĂpPbg𑗂܂B
        if ( !buf.empty( ) )
        {
			mSocket.write( handle, buf.size( ), buf.data( ) );
            buf.clear( );
            buf.shrink_to_fit( );
        }
    }
}
void cUDPServerManager::updateRecv( )
{
    // M̂΃obt@[oăpPbg̕ʂsB
    while ( !mSocket.emptyChunk( ) )
    {
        auto chunk = mSocket.popChunk( );
        if ( cUDPManager::getInstance( )->isConnectPacket( chunk ) ||
            ( mConnections.find( chunk.networkHandle ) != mConnections.end( ) ) )
        {
            cUDPManager::getInstance( )->onReceive( chunk );
        }
        else
        {
            // RlNVmȂ܂ܑMĂꍇB
        }
    }

    connection( );
    ping( );
}
void cUDPServerManager::sendDataBufferAdd( cNetworkHandle const & networkHandle, cPacketBuffer const & packetBuffer, bool reliable )
{
    auto itr = mConnections.find( networkHandle );
    if ( itr == mConnections.end( ) ) return;

    auto& buf = itr->second.buffer;

	// pPbg傫Ȃ肻ȂɑĂ܂܂B
	if ( 1024 < buf.size( ) )
	{
		mSocket.write( networkHandle, buf.size( ), buf.data( ) );
		buf.clear( );
		buf.shrink_to_fit( );
	}

	ubyte2 const& byte = packetBuffer.transferredBytes;
	cBuffer const& buffer = packetBuffer.buffer;

	if ( reliable )
	{
		std::vector<char> buf;
		buf.resize( buf.size( ) + byte );
		memcpy( buf.data( ) + buf.size( ) - byte, &buffer, byte );
		itr->second.reliableManager.append( std::move( buf ) );
	}
	else
	{
		buf.resize( buf.size( ) + byte );
		memcpy( buf.data( ) + buf.size( ) - byte, &buffer, byte );
	}
}
void cUDPServerManager::connection( )
{
    while ( auto p = cRequestManager::getInstance( )->getReqConnect( ) )
    {
        if ( !mIsAccept ) continue;

        cinder::app::console( ) << p->mNetworkHandle.ipAddress << ":" << p->mNetworkHandle.port << "";
        cinder::app::console( ) << "cUDPServerManager: " << "connecting..." << (int)mIdCount << std::endl;

        auto itr = mConnections.insert( std::make_pair( p->mNetworkHandle, std::move( cConnectionInfo( mIdCount ) ) ) );
        if ( itr.second )
        {
            cinder::app::console( ) << p->mNetworkHandle.ipAddress << ":" << p->mNetworkHandle.port << "";
            cinder::app::console( ) << "cUDPServerManager: " << "connect success!! " << (int)mIdCount << std::endl;

            mIdCount += 1;

            send( p->mNetworkHandle, new Packet::Response::cResConnect( ), false );

			// pingR[`𑖂点B
            using namespace Node::Action;
            auto act = repeat_forever::create( sequence::create( delay::create( 1.5F ), call_func::create( [ networkHandle = p->mNetworkHandle, this ]
            {
                send( networkHandle, new Packet::Event::cEvePing( ) );
                cinder::app::console( ) << "cUDPServerManager: " << "ping to " << (int)getPlayerId( networkHandle ) << std::endl;
            } ) ) );
            act->set_tag( itr.first->second.id );
            mRoot->run_action( act );
        }
        else
        {
            cinder::app::console( ) << p->mNetworkHandle.ipAddress << ":" << p->mNetworkHandle.port << "";
            cinder::app::console( ) << "cUDPServerManager: " << "connect faild " << (int)mIdCount << std::endl;
        }
    }
}
void cUDPServerManager::ping( )
{
    while ( auto p = cDeliverManager::getInstance( )->getDliPing( ) )
    {
        auto itr = mConnections.find( p->mNetworkHandle );
        if ( itr != mConnections.end( ) )
        {
            itr->second.closeSecond = cinder::app::getElapsedSeconds( ) + PING_HOLD_SECOND;
        }
    }

    for ( auto itr = mConnections.begin( ); itr != mConnections.end( ); )
    {
        // [J̏ꍇ̓JEg_E܂B
        if ( itr->first.ipAddress != Network::getLocalIpAddressHost( ) )
        {
            if ( itr->second.closeSecond < cinder::app::getElapsedSeconds( ) )
            {
                cinder::app::console( ) << itr->first.ipAddress << ":" << itr->first.port << "";
                cinder::app::console( ) << "cUDPServerManager: " << "disconnect" << itr->second.id << std::endl;
                mRoot->remove_action_by_tag( itr->second.id );
                mConnections.erase( itr++ );
                continue;
            }
        }
        ++itr;
    }
}
}<commit_msg>リコネクト出来るようにしました。<commit_after>#include <Network/cUDPServerManager.h>
#include <Network/cUDPManager.h>
#include <Network/cDeliverManager.h>
#include <Network/cEventManager.h>
#include <Network/cRequestManager.h>
#include <Network/cResponseManager.h>
#include <cinder/app/App.h>
#include <limits>
#include <Node/action.hpp>
#include <Utility/MessageBox.h>
#include <Network/IpHost.h>
namespace Network
{
cUDPServerManager::cUDPServerManager( )
{
	closeAccepter( );
	mRoot = Node::node::create( );
	mRoot->set_schedule_update( );
}
void cUDPServerManager::close( )
{
    mRoot.reset( );
    mSocket.close( );
    closeAccepter( );
}
void cUDPServerManager::open( )
{
    mRoot = Node::node::create( );
    mRoot->set_schedule_update( );
    mSocket.open( 25565 );
    openAccepter( );
}
void cUDPServerManager::closeAccepter( )
{
	mIsAccept = false;
	mIdCount = 0;
	mConnections.clear( );
}
void cUDPServerManager::openAccepter( )
{
    mIsAccept = true;
}
void cUDPServerManager::update( float delta )
{
    updateRecv( );
    updateSend( );
    mRoot->entry_update( delta );
}
ubyte1 cUDPServerManager::getPlayerId( cNetworkHandle const & handle )
{
    auto itr = mConnections.find( handle );
    if ( itr != mConnections.end( ) )
    {
        return itr->second.id;
    }
    else
    {
        throw std::runtime_error( "Networkhandle nothing" );
    }
}
void cUDPServerManager::updateSend( )
{
    // M̂΃obt@[ođB
    for ( auto& client : mConnections )
    {
		auto& handle = client.first;
		auto& buf = client.second.buffer;

		// CAuȃf[^l߂܂B
		auto reliableData = client.second.reliableManager.update( );
		std::copy( reliableData.begin(), reliableData.end(), std::back_inserter( buf ) );

        // ]ĂpPbg𑗂܂B
        if ( !buf.empty( ) )
        {
			mSocket.write( handle, buf.size( ), buf.data( ) );
            buf.clear( );
            buf.shrink_to_fit( );
        }
    }
}
void cUDPServerManager::updateRecv( )
{
    // M̂΃obt@[oăpPbg̕ʂsB
    while ( !mSocket.emptyChunk( ) )
    {
        auto chunk = mSocket.popChunk( );
        if ( cUDPManager::getInstance( )->isConnectPacket( chunk ) ||
            ( mConnections.find( chunk.networkHandle ) != mConnections.end( ) ) )
        {
            cUDPManager::getInstance( )->onReceive( chunk );
        }
        else
        {
            // RlNVmȂ܂ܑMĂꍇB
        }
    }

    connection( );
    ping( );
}
void cUDPServerManager::sendDataBufferAdd( cNetworkHandle const & networkHandle, cPacketBuffer const & packetBuffer, bool reliable )
{
    auto itr = mConnections.find( networkHandle );
    if ( itr == mConnections.end( ) ) return;

    auto& buf = itr->second.buffer;

	// pPbg傫Ȃ肻ȂɑĂ܂܂B
	if ( 1024 < buf.size( ) )
	{
		mSocket.write( networkHandle, buf.size( ), buf.data( ) );
		buf.clear( );
		buf.shrink_to_fit( );
	}

	ubyte2 const& byte = packetBuffer.transferredBytes;
	cBuffer const& buffer = packetBuffer.buffer;

	if ( reliable )
	{
		std::vector<char> buf;
		buf.resize( buf.size( ) + byte );
		memcpy( buf.data( ) + buf.size( ) - byte, &buffer, byte );
		itr->second.reliableManager.append( std::move( buf ) );
	}
	else
	{
		buf.resize( buf.size( ) + byte );
		memcpy( buf.data( ) + buf.size( ) - byte, &buffer, byte );
	}
}
void cUDPServerManager::connection( )
{
    while ( auto p = cRequestManager::getInstance( )->getReqConnect( ) )
    {
        if ( !mIsAccept ) continue;

        cinder::app::console( ) << p->mNetworkHandle.ipAddress << ":" << p->mNetworkHandle.port << "";
        cinder::app::console( ) << "cUDPServerManager: " << "connecting..." << (int)mIdCount << std::endl;

        auto itr = mConnections.insert( std::make_pair( p->mNetworkHandle, std::move( cConnectionInfo( mIdCount ) ) ) );
        if ( itr.second )
        {
            cinder::app::console( ) << p->mNetworkHandle.ipAddress << ":" << p->mNetworkHandle.port << "";
            cinder::app::console( ) << "cUDPServerManager: " << "connect success!! " << (int)mIdCount << std::endl;

            mIdCount += 1;

            send( p->mNetworkHandle, new Packet::Response::cResConnect( ), false );

			// pingR[`𑖂点B
            using namespace Node::Action;
            auto act = repeat_forever::create( sequence::create( delay::create( 1.5F ), call_func::create( [ networkHandle = p->mNetworkHandle, this ]
            {
                send( networkHandle, new Packet::Event::cEvePing( ) );
                cinder::app::console( ) << "cUDPServerManager: " << "ping to " << (int)getPlayerId( networkHandle ) << std::endl;
            } ) ) );
            act->set_tag( itr.first->second.id );
            mRoot->run_action( act );
        }
        else
        {
			// ĂѐڑĂꍇB

            cinder::app::console( ) << p->mNetworkHandle.ipAddress << ":" << p->mNetworkHandle.port << "";
            cinder::app::console( ) << "cUDPServerManager: " << "reconnect success!! " << (int)mIdCount << std::endl;

			send( p->mNetworkHandle, new Packet::Response::cResConnect( ), false );

			// pingR[`𑖂点B
			mRoot->remove_action_by_tag( itr.first->second.id );
			using namespace Node::Action;
			auto act = repeat_forever::create( sequence::create( delay::create( 1.5F ), call_func::create( [networkHandle = p->mNetworkHandle, this]
			{
				send( networkHandle, new Packet::Event::cEvePing( ) );
			cinder::app::console( ) << "cUDPServerManager: " << "ping to " << (int)getPlayerId( networkHandle ) << std::endl;
			} ) ) );
			act->set_tag( itr.first->second.id );
			mRoot->run_action( act );
        }
    }
}
void cUDPServerManager::ping( )
{
    while ( auto p = cDeliverManager::getInstance( )->getDliPing( ) )
    {
        auto itr = mConnections.find( p->mNetworkHandle );
        if ( itr != mConnections.end( ) )
        {
            itr->second.closeSecond = cinder::app::getElapsedSeconds( ) + PING_HOLD_SECOND;
        }
    }

    for ( auto itr = mConnections.begin( ); itr != mConnections.end( ); )
    {
        // [J̏ꍇ̓JEg_E܂B
        if ( itr->first.ipAddress != Network::getLocalIpAddressHost( ) )
        {
            if ( itr->second.closeSecond < cinder::app::getElapsedSeconds( ) )
            {
                cinder::app::console( ) << itr->first.ipAddress << ":" << itr->first.port << "";
                cinder::app::console( ) << "cUDPServerManager: " << "disconnect" << itr->second.id << std::endl;
                mRoot->remove_action_by_tag( itr->second.id );
                mConnections.erase( itr++ );
                continue;
            }
        }
        ++itr;
    }
}
}<|endoftext|>


<commit_before>/**
 * @file checksum.cc
 * @author Tomasz Lichon
 * @copyright (C) 2016 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

#include "checksum.h"

#include "messages.pb.h"

#include <sstream>

namespace one {
namespace messages {
namespace fuse {

Checksum::Checksum(std::unique_ptr<ProtocolServerMessage> serverMessage)
{
    if (!serverMessage->fuse_response().has_checksum())
        throw std::system_error{std::make_error_code(std::errc::protocol_error),
            "checksum field missing"};

    auto &message = *serverMessage->mutable_fuse_response()->mutable_checksum();

    message.mutable_value()->swap(m_value);
}

const std::string &Checksum::value() const { return m_value; }

std::string Checksum::toString() const
{
    std::stringstream ss;
    ss << "type: 'Checksum', value: '" << m_value;
    return ss.str();
}

} // namespace fuse
} // namespace messages
} // namespace one
<commit_msg>VFS-2197 Fail with proper error when sync has failed.<commit_after>/**
 * @file checksum.cc
 * @author Tomasz Lichon
 * @copyright (C) 2016 ACK CYFRONET AGH
 * @copyright This software is released under the MIT license cited in
 * 'LICENSE.txt'
 */

#include "checksum.h"

#include "messages.pb.h"
#include "messages/status.h"

#include <sstream>

namespace one {
namespace messages {
namespace fuse {

Checksum::Checksum(std::unique_ptr<ProtocolServerMessage> serverMessage)
{
    Status{*serverMessage->mutable_fuse_response()->mutable_status()}
        .throwOnError();

    if (!serverMessage->fuse_response().has_checksum())
        throw std::system_error{std::make_error_code(std::errc::protocol_error),
            "checksum field missing"};

    auto &message = *serverMessage->mutable_fuse_response()->mutable_checksum();

    message.mutable_value()->swap(m_value);
}

const std::string &Checksum::value() const { return m_value; }

std::string Checksum::toString() const
{
    std::stringstream ss;
    ss << "type: 'Checksum', value: '" << m_value;
    return ss.str();
}

} // namespace fuse
} // namespace messages
} // namespace one
<|endoftext|>


<commit_before><commit_msg>Invoke the right method (invokeDefault) if a plugin calls NPN_InvokeDefault on its own object.<commit_after><|endoftext|>


<commit_before><commit_msg>Disable tests while I investigate<commit_after><|endoftext|>


<commit_before>#pragma once

#include "Karabiner-VirtualHIDDevice/dist/include/karabiner_virtual_hid_device_methods.hpp"
#include "iokit_utility.hpp"
#include <IOKit/IOKitLib.h>
#include <IOKit/hidsystem/IOHIDShared.h>
#include <nod/nod.hpp>
#include <pqrs/osx/iokit_service_monitor.hpp>
#include <pqrs/osx/kern_return.hpp>

namespace krbn {
class virtual_hid_device_client final : public pqrs::dispatcher::extra::dispatcher_client {
public:
  nod::signal<void(void)> client_connected;
  nod::signal<void(void)> client_disconnected;
  nod::signal<void(void)> virtual_hid_keyboard_ready;

  virtual_hid_device_client(const virtual_hid_device_client&) = delete;

  virtual_hid_device_client(void) : dispatcher_client(),
                                    service_(IO_OBJECT_NULL),
                                    connect_(IO_OBJECT_NULL),
                                    connected_(false),
                                    virtual_hid_keyboard_ready_check_timer_(*this),
                                    virtual_hid_keyboard_ready_(false) {
  }

  virtual ~virtual_hid_device_client(void) {
    detach_from_dispatcher([this] {
      close_connection();

      service_monitor_ = nullptr;
    });
  }

  void async_connect(void) {
    enqueue_to_dispatcher([this] {
      if (auto matching_dictionary = IOServiceNameMatching(pqrs::karabiner_virtual_hid_device::get_virtual_hid_root_name())) {
        service_monitor_ = std::make_unique<pqrs::osx::iokit_service_monitor>(weak_dispatcher_,
                                                                              matching_dictionary);

        service_monitor_->service_matched.connect([this](auto&& registry_entry_id, auto&& service_ptr) {
          close_connection();

          // Use the last matched service.
          open_connection(*service_ptr);
        });

        service_monitor_->service_terminated.connect([this](auto&& registry_entry_id) {
          close_connection();

          // Use the next service
          service_monitor_->async_invoke_service_matched();
        });

        service_monitor_->async_start();

        logger::get_logger()->info("virtual_hid_device_client is started.");

        CFRelease(matching_dictionary);
      }
    });
  }

  void async_close(void) {
    enqueue_to_dispatcher([this] {
      close_connection();
    });
  }

  bool is_connected(void) const {
    return connected_;
  }

  bool is_virtual_hid_keyboard_ready(void) const {
    return virtual_hid_keyboard_ready_;
  }

  void async_initialize_virtual_hid_keyboard(const pqrs::karabiner_virtual_hid_device::properties::keyboard_initialization& properties) {
    enqueue_to_dispatcher([this, properties] {
      if (virtual_hid_keyboard_ready_ &&
          virtual_hid_keyboard_properties_ == properties) {
        return;
      }

      virtual_hid_keyboard_properties_ = properties;
      virtual_hid_keyboard_ready_ = false;

      logger::get_logger()->info("initialize_virtual_hid_keyboard");
      logger::get_logger()->info("  country_code:{0}", static_cast<uint32_t>(virtual_hid_keyboard_properties_.country_code));

      if (!connect_) {
        logger::get_logger()->warn("connect_ is IO_OBJECT_NULL");
        return;
      }

      bool result = pqrs::karabiner_virtual_hid_device_methods::initialize_virtual_hid_keyboard(connect_, virtual_hid_keyboard_properties_);

      if (result == kIOReturnSuccess) {
        virtual_hid_keyboard_ready_check_timer_.start(
            [this] {
              if (!connect_) {
                virtual_hid_keyboard_ready_check_timer_.stop();
                return;
              }

              bool ready = false;
              if (pqrs::karabiner_virtual_hid_device_methods::is_virtual_hid_keyboard_ready(connect_, ready) == kIOReturnSuccess) {
                if (ready) {
                  virtual_hid_keyboard_ready_check_timer_.stop();
                  virtual_hid_keyboard_ready_ = true;

                  enqueue_to_dispatcher([this] {
                    virtual_hid_keyboard_ready();
                  });
                }
              }
            },
            std::chrono::milliseconds(1000));
      }
    });
  }

  void async_terminate_virtual_hid_keyboard(void) {
    enqueue_to_dispatcher([this] {
      virtual_hid_keyboard_ready_check_timer_.stop();
      virtual_hid_keyboard_ready_ = false;

      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::terminate_virtual_hid_keyboard(connect_);
      }
    });
  }

  void async_post_keyboard_input_report(const pqrs::karabiner::driverkit::virtual_hid_device_driver::hid_report::keyboard_input& report) {
    enqueue_to_dispatcher([this, report] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::post_keyboard_input_report(connect_, report);
      }
    });
  }

  void async_post_keyboard_input_report(const pqrs::karabiner::driverkit::virtual_hid_device_driver::hid_report::consumer_input& report) {
    enqueue_to_dispatcher([this, report] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::post_keyboard_input_report(connect_, report);
      }
    });
  }

  void async_post_keyboard_input_report(const pqrs::karabiner::driverkit::virtual_hid_device_driver::hid_report::apple_vendor_top_case_input& report) {
    enqueue_to_dispatcher([this, report] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::post_keyboard_input_report(connect_, report);
      }
    });
  }

  void async_post_keyboard_input_report(const pqrs::karabiner::driverkit::virtual_hid_device_driver::hid_report::apple_vendor_keyboard_input& report) {
    enqueue_to_dispatcher([this, report] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::post_keyboard_input_report(connect_, report);
      }
    });
  }

  void async_reset_virtual_hid_keyboard(void) {
    enqueue_to_dispatcher([this] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::reset_virtual_hid_keyboard(connect_);
      }
    });
  }

  void async_initialize_virtual_hid_pointing(void) {
    enqueue_to_dispatcher([this] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::initialize_virtual_hid_pointing(connect_);
      }
    });
  }

  void async_terminate_virtual_hid_pointing(void) {
    enqueue_to_dispatcher([this] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::terminate_virtual_hid_pointing(connect_);
      }
    });
  }

  void async_post_pointing_input_report(const pqrs::karabiner::driverkit::virtual_hid_device_driver::hid_report::pointing_input& report) {
    enqueue_to_dispatcher([this, report] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::post_pointing_input_report(connect_, report);
      }
    });
  }

  void async_reset_virtual_hid_pointing(void) {
    enqueue_to_dispatcher([this] {
      if (connect_) {
        pqrs::karabiner_virtual_hid_device_methods::reset_virtual_hid_pointing(connect_);
      }
    });
  }

private:
  // This method is executed in the dispatcher thread.
  void open_connection(io_service_t s) {
    service_ = s;
    IOObjectRetain(service_);

    pqrs::osx::kern_return r = IOServiceOpen(service_, mach_task_self(), kIOHIDServerConnectType, &connect_);
    if (r) {
      logger::get_logger()->info("virtual_hid_device_client is opened.");

      connected_ = true;

      enqueue_to_dispatcher([this] {
        client_connected();
      });

    } else {
      logger::get_logger()->error("virtual_hid_device_client::open_connection is failed: {0}",
                                  r.to_string());
      connect_ = IO_OBJECT_NULL;
    }
  }

  // This method is executed in the dispatcher thread.
  void close_connection(void) {
    if (connect_) {
      pqrs::osx::kern_return r = IOServiceClose(connect_);
      if (!r) {
        logger::get_logger()->error("virtual_hid_device_client::close_connection error: {0}",
                                    r.to_string());
      }
      connect_ = IO_OBJECT_NULL;

      connected_ = false;

      enqueue_to_dispatcher([this] {
        client_disconnected();
      });

      logger::get_logger()->info("virtual_hid_device_client is closed.");
    }

    if (service_) {
      IOObjectRelease(service_);
      service_ = IO_OBJECT_NULL;
    }

    virtual_hid_keyboard_ready_check_timer_.stop();
    virtual_hid_keyboard_ready_ = false;
  }

  std::unique_ptr<pqrs::osx::iokit_service_monitor> service_monitor_;
  io_service_t service_;
  io_connect_t connect_;
  std::atomic<bool> connected_;

  pqrs::dispatcher::extra::timer virtual_hid_keyboard_ready_check_timer_;
  std::atomic<bool> virtual_hid_keyboard_ready_;
  pqrs::karabiner_virtual_hid_device::properties::keyboard_initialization virtual_hid_keyboard_properties_;
};
} // namespace krbn
<commit_msg>Remove virtual_hid_device_client<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2016 neurodata (http://neurodata.io/)
 * Written by Disa Mhembere (disa@jhu.edu)
 *
 * This file is part of k-par-means
 *
 * 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 CURRENT_KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <limits>
#include <numa.h>

#include "signal.h"
#include "io.hpp"
#include "kmeans.hpp"

#include "kmeans_coordinator.hpp"
#include "kmeans_task_coordinator.hpp"
#include "util.hpp"

static void print_usage();

int main(int argc, char* argv[]) {

    if (argc < 5) {
        print_usage();
        exit(EXIT_FAILURE);
    }

	int opt;
    std::string datafn = std::string(argv[1]);
    size_t nrow = atol(argv[2]);
    size_t ncol = atol(argv[3]);
    unsigned k = atol(argv[4]);

    std::string dist_type = "eucl";
    std::string centersfn = "";
	size_t max_iters=std::numeric_limits<size_t>::max();
	std::string init = "kmeanspp";
	unsigned nthread = kpmbase::get_num_omp_threads();
	int num_opts = 0;
	double tolerance = -1;
    bool use_min_tri = false;
    bool pthread = false;
    unsigned nnodes = numa_num_task_nodes();
    std::string outdir = "";

    // Increase by 3 -- getopt ignores argv[0]
	argv += 3;
	argc -= 3;

	signal(SIGINT, kpmbase::int_handler);
	while ((opt = getopt(argc, argv, "l:i:t:T:d:C:mpN:o:")) != -1) {
		num_opts++;
		switch (opt) {
			case 'l':
				tolerance = atof(optarg);
				num_opts++;
				break;
			case 'i':
				max_iters = atol(optarg);
				num_opts++;
				break;
			case 't':
				init = optarg;
				num_opts++;
				break;
			case 'T':
				nthread = atoi(optarg);
				num_opts++;
				break;
			case 'd':
				dist_type = std::string(optarg);
				num_opts++;
				break;
			case 'C':
				centersfn = std::string(optarg);
                BOOST_ASSERT_MSG(kpmbase::is_file_exist(centersfn.c_str()),
                        "Centers file name doesn't exit!");
                init = "none"; // Ignore whatever you pass in
				num_opts++;
				break;
			case 'm':
				use_min_tri = true;
				num_opts++;
				break;
			case 'p':
				pthread = true;
				num_opts++;
				break;
			case 'N':
				nnodes = atoi(optarg);
				num_opts++;
				break;
			case 'o':
				outdir = std::string(optarg);
				num_opts++;
				break;
			default:
				print_usage();
		}
	}

    if (outdir.empty())
        fprintf(stderr, "\n\n**[WARNING]**: No output dir specified with '-o' "
                " flag means no output will be saved!\n\n");

    BOOST_ASSERT_MSG(!(init=="none" && centersfn.empty()),
            "Centers file name doesn't exit!");

    if (kpmbase::filesize(datafn.c_str()) != (sizeof(double)*nrow*ncol))
        throw kpmbase::io_exception("File size does not match input size.");

    double* p_centers = NULL;
    kpmbase::kmeans_t ret;

    if (kpmbase::is_file_exist(centersfn.c_str())) {
        p_centers = new double [k*ncol];
        kpmbase::bin_io<double> br2(centersfn, k, ncol);
        br2.read(p_centers);
        printf("Read centers!\n");
    } else
        printf("No centers to read ..\n");
    if (pthread) {
        if (use_min_tri) {
            kpmprune::kmeans_task_coordinator::ptr kc =
                kpmprune::kmeans_task_coordinator::create(
                    datafn, nrow, ncol, k, max_iters, nnodes, nthread, p_centers,
                    init, tolerance, dist_type);
            ret = kc->run_kmeans();
        } else {
            kpmeans::kmeans_coordinator::ptr kc =
                kpmeans::kmeans_coordinator::create(datafn,
                    nrow, ncol, k, max_iters, nnodes, nthread, p_centers,
                    init, tolerance, dist_type);
            ret = kc->run_kmeans();
        }
    } else {
        kpmbase::bin_io<double> br(datafn, nrow, ncol);
        double* p_data = new double [nrow*ncol];
        br.read(p_data);
        printf("Read data!\n");

        unsigned* p_clust_asgns = new unsigned [nrow];
        size_t* p_clust_asgn_cnt = new size_t [k];

        if (NULL == p_centers) // We have no preallocated centers
            p_centers = new double [k*ncol];

        if (use_min_tri) {
            ret = kpmeans::omp::compute_min_kmeans(p_data, p_centers, p_clust_asgns,
                    p_clust_asgn_cnt, nrow, ncol, k, max_iters,
                    nthread, init, tolerance, dist_type);
        } else {
            ret = kpmeans::omp::compute_kmeans(p_data, p_centers, p_clust_asgns,
                    p_clust_asgn_cnt, nrow, ncol, k, max_iters,
                    nthread, init, tolerance, dist_type);
        }

        delete [] p_clust_asgns;
        delete [] p_clust_asgn_cnt;
        delete [] p_data;
    }

    if (!outdir.empty()) {
        printf("\nWriting output to '%s'\n", outdir.c_str());
        ret.write(outdir);
    }

    if (p_centers) delete [] p_centers;

    return EXIT_SUCCESS;
}

void print_usage() {
	fprintf(stderr,
        "kpmeans data-file num-rows num-cols k [alg-options]\n");
    fprintf(stderr, "-t type: type of initialization for kmeans"
           " ['random', 'forgy', 'kmeanspp', 'none']\n");
    fprintf(stderr, "-T num_thread: The number of threads to run\n");
    fprintf(stderr, "-i iters: maximum number of iterations\n");
    fprintf(stderr, "-C File with initial clusters in same format as data\n");
    fprintf(stderr, "-l tolerance for convergence (1E-6)\n");
    fprintf(stderr, "-d Distance metric [eucl,cos]\n");
    fprintf(stderr, "-m Use the minimal triangle inequality (~Elkan's alg)\n");
    fprintf(stderr, "-p Use p-threads for ||ization rather than OMP\n");
    fprintf(stderr, "-N No. of numa nodes you want to use\n");
    fprintf(stderr, "-o Write output to an output directory of this name\n");
    exit(EXIT_FAILURE);
}
<commit_msg>knori: made pthreads + prune default. Commit closes #21<commit_after>/*
 * Copyright 2016 neurodata (http://neurodata.io/)
 * Written by Disa Mhembere (disa@jhu.edu)
 *
 * This file is part of k-par-means
 *
 * 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 CURRENT_KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <limits>
#include <numa.h>

#include "signal.h"
#include "io.hpp"
#include "kmeans.hpp"

#include "kmeans_coordinator.hpp"
#include "kmeans_task_coordinator.hpp"
#include "util.hpp"

static void print_usage();

int main(int argc, char* argv[]) {

    if (argc < 5) {
        print_usage();
        exit(EXIT_FAILURE);
    }

	int opt;
    std::string datafn = std::string(argv[1]);
    size_t nrow = atol(argv[2]);
    size_t ncol = atol(argv[3]);
    unsigned k = atol(argv[4]);

    std::string dist_type = "eucl";
    std::string centersfn = "";
	size_t max_iters=std::numeric_limits<size_t>::max();
	std::string init = "kmeanspp";
	unsigned nthread = kpmbase::get_num_omp_threads();
	int num_opts = 0;
	double tolerance = -1;
    bool no_prune = false;
    bool omp = false;
    unsigned nnodes = numa_num_task_nodes();
    std::string outdir = "";

    // Increase by 3 -- getopt ignores argv[0]
	argv += 3;
	argc -= 3;

	signal(SIGINT, kpmbase::int_handler);
	while ((opt = getopt(argc, argv, "l:i:t:T:d:C:PON:o:")) != -1) {
		num_opts++;
		switch (opt) {
			case 'l':
				tolerance = atof(optarg);
				num_opts++;
				break;
			case 'i':
				max_iters = atol(optarg);
				num_opts++;
				break;
			case 't':
				init = optarg;
				num_opts++;
				break;
			case 'T':
				nthread = atoi(optarg);
				num_opts++;
				break;
			case 'd':
				dist_type = std::string(optarg);
				num_opts++;
				break;
			case 'C':
				centersfn = std::string(optarg);
                BOOST_ASSERT_MSG(kpmbase::is_file_exist(centersfn.c_str()),
                        "Centers file name doesn't exit!");
                init = "none"; // Ignore whatever you pass in
				num_opts++;
				break;
			case 'P':
				no_prune = true;
				num_opts++;
				break;
			case 'O':
				omp = true;
				num_opts++;
				break;
			case 'N':
				nnodes = atoi(optarg);
				num_opts++;
				break;
			case 'o':
				outdir = std::string(optarg);
				num_opts++;
				break;
			default:
				print_usage();
		}
	}

    if (outdir.empty())
        fprintf(stderr, "\n\n**[WARNING]**: No output dir specified with '-o' "
                " flag means no output will be saved!\n\n");

    BOOST_ASSERT_MSG(!(init=="none" && centersfn.empty()),
            "Centers file name doesn't exit!");

    if (kpmbase::filesize(datafn.c_str()) != (sizeof(double)*nrow*ncol))
        throw kpmbase::io_exception("File size does not match input size.");

    double* p_centers = NULL;
    kpmbase::kmeans_t ret;

    if (kpmbase::is_file_exist(centersfn.c_str())) {
        p_centers = new double [k*ncol];
        kpmbase::bin_io<double> br2(centersfn, k, ncol);
        br2.read(p_centers);
        printf("Read centers!\n");
    } else
        printf("No centers to read ..\n");
    if (omp) {
        kpmbase::bin_io<double> br(datafn, nrow, ncol);
        double* p_data = new double [nrow*ncol];
        br.read(p_data);
        printf("Read data!\n");

        unsigned* p_clust_asgns = new unsigned [nrow];
        size_t* p_clust_asgn_cnt = new size_t [k];

        if (NULL == p_centers) // We have no preallocated centers
            p_centers = new double [k*ncol];

        if (no_prune) {
            ret = kpmeans::omp::compute_kmeans(p_data, p_centers, p_clust_asgns,
                    p_clust_asgn_cnt, nrow, ncol, k, max_iters,
                    nthread, init, tolerance, dist_type);
        } else {
            ret = kpmeans::omp::compute_min_kmeans(p_data, p_centers, p_clust_asgns,
                    p_clust_asgn_cnt, nrow, ncol, k, max_iters,
                    nthread, init, tolerance, dist_type);
        }

        delete [] p_clust_asgns;
        delete [] p_clust_asgn_cnt;
        delete [] p_data;
    } else {
        if (no_prune) {
            kpmeans::kmeans_coordinator::ptr kc =
                kpmeans::kmeans_coordinator::create(datafn,
                    nrow, ncol, k, max_iters, nnodes, nthread, p_centers,
                    init, tolerance, dist_type);
            ret = kc->run_kmeans();
        } else {
            kpmprune::kmeans_task_coordinator::ptr kc =
                kpmprune::kmeans_task_coordinator::create(
                    datafn, nrow, ncol, k, max_iters, nnodes, nthread, p_centers,
                    init, tolerance, dist_type);
            ret = kc->run_kmeans();
        }
    }

    if (!outdir.empty()) {
        printf("\nWriting output to '%s'\n", outdir.c_str());
        ret.write(outdir);
    }

    if (p_centers) delete [] p_centers;

    return EXIT_SUCCESS;
}

void print_usage() {
	fprintf(stderr,
        "kpmeans data-file num-rows num-cols k [alg-options]\n");
    fprintf(stderr, "-t type: type of initialization for kmeans"
           " ['random', 'forgy', 'kmeanspp', 'none']\n");
    fprintf(stderr, "-T num_thread: The number of threads to run\n");
    fprintf(stderr, "-i iters: maximum number of iterations\n");
    fprintf(stderr, "-C File with initial clusters in same format as data\n");
    fprintf(stderr, "-l tolerance for convergence (1E-6)\n");
    fprintf(stderr, "-d Distance metric [eucl,cos]\n");
    fprintf(stderr, "-P DO NOT use the minimal triangle inequality (~Elkan's alg)\n");
    fprintf(stderr, "-O Use OpenMP for ||ization rather than fast pthreads\n");
    fprintf(stderr, "-N No. of numa nodes you want to use\n");
    fprintf(stderr, "-o Write output to an output directory of this name\n");
    exit(EXIT_FAILURE);
}
<|endoftext|>


<commit_before>//===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This diagnostic client prints out their diagnostic messages.
//
//===----------------------------------------------------------------------===//

#include "TextDiagnosticPrinter.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Streams.h"
#include <string>
using namespace clang;

static llvm::cl::opt<bool>
NoShowColumn("fno-show-column",
             llvm::cl::desc("Do not include column number on diagnostics"));
static llvm::cl::opt<bool>
NoCaretDiagnostics("fno-caret-diagnostics",
                   llvm::cl::desc("Do not include source line and caret with"
                                  " diagnostics"));

void TextDiagnosticPrinter::
PrintIncludeStack(FullSourceLoc Pos) {
  if (Pos.isInvalid()) return;

  Pos = Pos.getLogicalLoc();

  // Print out the other include frames first.
  PrintIncludeStack(Pos.getIncludeLoc());
  unsigned LineNo = Pos.getLineNumber();

  llvm::cerr << "In file included from " << Pos.getSourceName()
             << ":" << LineNo << ":\n";
}

/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
/// any characters in LineNo that intersect the SourceRange.
void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
                                           SourceManager& SourceMgr,
                                           unsigned LineNo, unsigned FileID,
                                           std::string &CaratLine,
                                           const std::string &SourceLine) {
  assert(CaratLine.size() == SourceLine.size() &&
         "Expect a correspondence between source and carat line!");
  if (!R.isValid()) return;

  SourceLocation LogicalStart = SourceMgr.getLogicalLoc(R.getBegin());
  unsigned StartLineNo = SourceMgr.getLineNumber(LogicalStart);
  if (StartLineNo > LineNo || LogicalStart.getFileID() != FileID)
    return;  // No intersection.

  SourceLocation LogicalEnd = SourceMgr.getLogicalLoc(R.getEnd());
  unsigned EndLineNo = SourceMgr.getLineNumber(LogicalEnd);
  if (EndLineNo < LineNo || LogicalStart.getFileID() != FileID)
    return;  // No intersection.

  // Compute the column number of the start.
  unsigned StartColNo = 0;
  if (StartLineNo == LineNo) {
    StartColNo = SourceMgr.getLogicalColumnNumber(R.getBegin());
    if (StartColNo) --StartColNo;  // Zero base the col #.
  }

  // Pick the first non-whitespace column.
  while (StartColNo < SourceLine.size() &&
         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
    ++StartColNo;

  // Compute the column number of the end.
  unsigned EndColNo = CaratLine.size();
  if (EndLineNo == LineNo) {
    EndColNo = SourceMgr.getLogicalColumnNumber(R.getEnd());
    if (EndColNo) {
      --EndColNo;  // Zero base the col #.

      // Add in the length of the token, so that we cover multi-char tokens.
      EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr);
    } else {
      EndColNo = CaratLine.size();
    }
  }

  // Pick the last non-whitespace column.
  while (EndColNo-1 &&
         (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
    --EndColNo;

  // Fill the range with ~'s.
  assert(StartColNo <= EndColNo && "Invalid range!");
  for (unsigned i = StartColNo; i != EndColNo; ++i)
    CaratLine[i] = '~';
}

void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags,
                                             Diagnostic::Level Level,
                                             FullSourceLoc Pos,
                                             diag::kind ID,
                                             const std::string *Strs,
                                             unsigned NumStrs,
                                             const SourceRange *Ranges,
                                             unsigned NumRanges) {
  unsigned LineNo = 0, ColNo = 0;
  unsigned FileID = 0;
  const char *LineStart = 0, *LineEnd = 0;

  if (Pos.isValid()) {
    FullSourceLoc LPos = Pos.getLogicalLoc();
    LineNo = LPos.getLineNumber();
    FileID = LPos.getLocation().getFileID();

    // First, if this diagnostic is not in the main file, print out the
    // "included from" lines.
    if (LastWarningLoc != LPos.getIncludeLoc()) {
      LastWarningLoc = LPos.getIncludeLoc();
      PrintIncludeStack(LastWarningLoc);
    }

    // Compute the column number.  Rewind from the current position to the start
    // of the line.
    ColNo = LPos.getColumnNumber();
    const char *TokLogicalPtr = LPos.getCharacterData();
    LineStart = TokLogicalPtr-ColNo+1;  // Column # is 1-based

    // Compute the line end.  Scan forward from the error position to the end of
    // the line.
    const llvm::MemoryBuffer *Buffer = LPos.getBuffer();
    const char *BufEnd = Buffer->getBufferEnd();
    LineEnd = TokLogicalPtr;
    while (LineEnd != BufEnd &&
           *LineEnd != '\n' && *LineEnd != '\r')
      ++LineEnd;

    llvm::cerr << Buffer->getBufferIdentifier()
               << ":" << LineNo << ":";
    if (ColNo && !NoShowColumn)
      llvm::cerr << ColNo << ":";
    llvm::cerr << " ";
  }

  switch (Level) {
  default: assert(0 && "Unknown diagnostic type!");
  case Diagnostic::Note:    llvm::cerr << "note: "; break;
  case Diagnostic::Warning: llvm::cerr << "warning: "; break;
  case Diagnostic::Error:   llvm::cerr << "error: "; break;
  case Diagnostic::Fatal:   llvm::cerr << "fatal error: "; break;
    break;
  }

  llvm::cerr << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";

  if (!NoCaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) && !Ranges)) {
    // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
    LastLoc = Pos;

    // Get the line of the source file.
    std::string SourceLine(LineStart, LineEnd);

    // Create a line for the carat that is filled with spaces that is the same
    // length as the line of source code.
    std::string CaratLine(LineEnd-LineStart, ' ');

    // Highlight all of the characters covered by Ranges with ~ characters.
    for (unsigned i = 0; i != NumRanges; ++i)
      HighlightRange(Ranges[i], Pos.getManager(), LineNo, FileID,
                     CaratLine, SourceLine);

    // Next, insert the carat itself.
    if (ColNo-1 < CaratLine.size())
      CaratLine[ColNo-1] = '^';
    else
      CaratLine.push_back('^');

    // Scan the source line, looking for tabs.  If we find any, manually expand
    // them to 8 characters and update the CaratLine to match.
    for (unsigned i = 0; i != SourceLine.size(); ++i) {
      if (SourceLine[i] != '\t') continue;

      // Replace this tab with at least one space.
      SourceLine[i] = ' ';

      // Compute the number of spaces we need to insert.
      unsigned NumSpaces = ((i+8)&~7) - (i+1);
      assert(NumSpaces < 8 && "Invalid computation of space amt");

      // Insert spaces into the SourceLine.
      SourceLine.insert(i+1, NumSpaces, ' ');

      // Insert spaces or ~'s into CaratLine.
      CaratLine.insert(i+1, NumSpaces, CaratLine[i] == '~' ? '~' : ' ');
    }

    // Finally, remove any blank spaces from the end of CaratLine.
    while (CaratLine[CaratLine.size()-1] == ' ')
      CaratLine.erase(CaratLine.end()-1);

    // Emit what we have computed.
    llvm::cerr << SourceLine << "\n";
    llvm::cerr << CaratLine << "\n";
  }
}
<commit_msg><commit_after>//===--- TextDiagnosticPrinter.cpp - Diagnostic Printer -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This diagnostic client prints out their diagnostic messages.
//
//===----------------------------------------------------------------------===//

#include "TextDiagnosticPrinter.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Lexer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Streams.h"
#include <string>
using namespace clang;

static llvm::cl::opt<bool>
NoShowColumn("fno-show-column",
             llvm::cl::desc("Do not include column number on diagnostics"));
static llvm::cl::opt<bool>
NoCaretDiagnostics("fno-caret-diagnostics",
                   llvm::cl::desc("Do not include source line and caret with"
                                  " diagnostics"));

void TextDiagnosticPrinter::
PrintIncludeStack(FullSourceLoc Pos) {
  if (Pos.isInvalid()) return;

  Pos = Pos.getLogicalLoc();

  // Print out the other include frames first.
  PrintIncludeStack(Pos.getIncludeLoc());
  unsigned LineNo = Pos.getLineNumber();

  llvm::cerr << "In file included from " << Pos.getSourceName()
             << ":" << LineNo << ":\n";
}

/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
/// any characters in LineNo that intersect the SourceRange.
void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
                                           SourceManager& SourceMgr,
                                           unsigned LineNo, unsigned FileID,
                                           std::string &CaratLine,
                                           const std::string &SourceLine) {
  assert(CaratLine.size() == SourceLine.size() &&
         "Expect a correspondence between source and carat line!");
  if (!R.isValid()) return;

  SourceLocation LogicalStart = SourceMgr.getLogicalLoc(R.getBegin());
  unsigned StartLineNo = SourceMgr.getLineNumber(LogicalStart);
  if (StartLineNo > LineNo || LogicalStart.getFileID() != FileID)
    return;  // No intersection.

  SourceLocation LogicalEnd = SourceMgr.getLogicalLoc(R.getEnd());
  unsigned EndLineNo = SourceMgr.getLineNumber(LogicalEnd);
  if (EndLineNo < LineNo || LogicalStart.getFileID() != FileID)
    return;  // No intersection.

  // Compute the column number of the start.
  unsigned StartColNo = 0;
  if (StartLineNo == LineNo) {
    StartColNo = SourceMgr.getLogicalColumnNumber(R.getBegin());
    if (StartColNo) --StartColNo;  // Zero base the col #.
  }

  // Pick the first non-whitespace column.
  while (StartColNo < SourceLine.size() &&
         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
    ++StartColNo;

  // Compute the column number of the end.
  unsigned EndColNo = CaratLine.size();
  if (EndLineNo == LineNo) {
    EndColNo = SourceMgr.getLogicalColumnNumber(R.getEnd());
    if (EndColNo) {
      --EndColNo;  // Zero base the col #.

      // Add in the length of the token, so that we cover multi-char tokens.
      EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr);
    } else {
      EndColNo = CaratLine.size();
    }
  }

  // Pick the last non-whitespace column.
  while (EndColNo-1 &&
         (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
    --EndColNo;

  // Fill the range with ~'s.
  assert(StartColNo <= EndColNo && "Invalid range!");
  for (unsigned i = StartColNo; i != EndColNo; ++i)
    CaratLine[i] = '~';
}

void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic &Diags,
                                             Diagnostic::Level Level,
                                             FullSourceLoc Pos,
                                             diag::kind ID,
                                             const std::string *Strs,
                                             unsigned NumStrs,
                                             const SourceRange *Ranges,
                                             unsigned NumRanges) {
  unsigned LineNo = 0, ColNo = 0;
  unsigned FileID = 0;
  const char *LineStart = 0, *LineEnd = 0;

  if (Pos.isValid()) {
    FullSourceLoc LPos = Pos.getLogicalLoc();
    LineNo = LPos.getLineNumber();
    FileID = LPos.getLocation().getFileID();

    // First, if this diagnostic is not in the main file, print out the
    // "included from" lines.
    if (LastWarningLoc != LPos.getIncludeLoc()) {
      LastWarningLoc = LPos.getIncludeLoc();
      PrintIncludeStack(LastWarningLoc);
    }

    // Compute the column number.  Rewind from the current position to the start
    // of the line.
    ColNo = LPos.getColumnNumber();
    const char *TokLogicalPtr = LPos.getCharacterData();
    LineStart = TokLogicalPtr-ColNo+1;  // Column # is 1-based

    // Compute the line end.  Scan forward from the error position to the end of
    // the line.
    const llvm::MemoryBuffer *Buffer = LPos.getBuffer();
    const char *BufEnd = Buffer->getBufferEnd();
    LineEnd = TokLogicalPtr;
    while (LineEnd != BufEnd &&
           *LineEnd != '\n' && *LineEnd != '\r')
      ++LineEnd;

    llvm::cerr << Buffer->getBufferIdentifier()
               << ":" << LineNo << ":";
    if (ColNo && !NoShowColumn)
      llvm::cerr << ColNo << ":";
    llvm::cerr << " ";
  }

  switch (Level) {
  default: assert(0 && "Unknown diagnostic type!");
  case Diagnostic::Note:    llvm::cerr << "note: "; break;
  case Diagnostic::Warning: llvm::cerr << "warning: "; break;
  case Diagnostic::Error:   llvm::cerr << "error: "; break;
  case Diagnostic::Fatal:   llvm::cerr << "fatal error: "; break;
    break;
  }

  llvm::cerr << FormatDiagnostic(Diags, Level, ID, Strs, NumStrs) << "\n";

  if (!NoCaretDiagnostics && Pos.isValid() && ((LastLoc != Pos) || Ranges)) {
    // Cache the LastLoc, it allows us to omit duplicate source/caret spewage.
    LastLoc = Pos;

    // Get the line of the source file.
    std::string SourceLine(LineStart, LineEnd);

    // Create a line for the carat that is filled with spaces that is the same
    // length as the line of source code.
    std::string CaratLine(LineEnd-LineStart, ' ');

    // Highlight all of the characters covered by Ranges with ~ characters.
    for (unsigned i = 0; i != NumRanges; ++i)
      HighlightRange(Ranges[i], Pos.getManager(), LineNo, FileID,
                     CaratLine, SourceLine);

    // Next, insert the carat itself.
    if (ColNo-1 < CaratLine.size())
      CaratLine[ColNo-1] = '^';
    else
      CaratLine.push_back('^');

    // Scan the source line, looking for tabs.  If we find any, manually expand
    // them to 8 characters and update the CaratLine to match.
    for (unsigned i = 0; i != SourceLine.size(); ++i) {
      if (SourceLine[i] != '\t') continue;

      // Replace this tab with at least one space.
      SourceLine[i] = ' ';

      // Compute the number of spaces we need to insert.
      unsigned NumSpaces = ((i+8)&~7) - (i+1);
      assert(NumSpaces < 8 && "Invalid computation of space amt");

      // Insert spaces into the SourceLine.
      SourceLine.insert(i+1, NumSpaces, ' ');

      // Insert spaces or ~'s into CaratLine.
      CaratLine.insert(i+1, NumSpaces, CaratLine[i] == '~' ? '~' : ' ');
    }

    // Finally, remove any blank spaces from the end of CaratLine.
    while (CaratLine[CaratLine.size()-1] == ' ')
      CaratLine.erase(CaratLine.end()-1);

    // Emit what we have computed.
    llvm::cerr << SourceLine << "\n";
    llvm::cerr << CaratLine << "\n";
  }
}
<|endoftext|>


<commit_before><commit_msg>put alignments in the right place<commit_after><|endoftext|>


<commit_before>/*
 * This file is part of Wireless Display Software for Linux OS
 *
 * Copyright (C) 2014 Intel Corporation.
 *
 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <algorithm>
#include <memory>

#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#include "mirac-network.hpp"

#define MIRAC_MAX_NAMELEN       255

MiracNetwork::MiracNetwork ()
{
    Init();
}

MiracNetwork::MiracNetwork (int conn_handle)
{
    Init();
    handle = conn_handle;
}

MiracNetwork::~MiracNetwork ()
{
    Close();
}

void MiracNetwork::Init ()
{
    long ps;

    handle = -1;

    ps = sysconf(_SC_PAGESIZE);
    page_size = (ps <= 0) ? 4096 : static_cast<size_t> (ps);

    conn_ares = NULL;
}

void MiracNetwork::Close ()
{
    if (handle >= 0)
        close(handle);
    handle = -1;

    if (conn_ares)
    {
        freeaddrinfo(reinterpret_cast<struct addrinfo *> (conn_ares));
        conn_ares = NULL;
    }
}

void MiracNetwork::Bind (const char *address, const char *service)
{
    int ec;
    int reuse = 1;
    struct addrinfo *addr_res = NULL;
    struct addrinfo *bind_addr;
    struct addrinfo addr_hint;

    Close();

    memset(&addr_hint, 0x00, sizeof(addr_hint));
    addr_hint.ai_flags = AI_PASSIVE;
    ec = getaddrinfo(address, service, &addr_hint, &addr_res);
    if (ec)
        throw MiracException(gai_strerror(ec), __FUNCTION__);
    bind_addr = addr_res;
    while (bind_addr)
    {
        /* note, the SOCK_NONBLOCK is specific to Linux 2.6.27+,
         * on other platforms use either fcntl() or ioctl(h, FIONBIO, 1) */
        handle = socket(addr_res->ai_family,
            addr_res->ai_socktype | SOCK_NONBLOCK, addr_res->ai_protocol);
        if (handle < 0)
            throw MiracException(errno, "socket()", __FUNCTION__);
        if (setsockopt(handle, SOL_SOCKET, SO_REUSEADDR,
            &reuse, sizeof(reuse)))
            throw MiracException(errno, "setsockopt()", __FUNCTION__);
	if (bind(handle, bind_addr->ai_addr, bind_addr->ai_addrlen) == 0)
           break;
        else if (!bind_addr->ai_next)
            throw MiracException(errno, "bind()", __FUNCTION__);
        close(handle);
	bind_addr = bind_addr->ai_next;
    }
    freeaddrinfo(addr_res);

    if (listen(handle, 1))
        throw MiracException(errno, "listen()", __FUNCTION__);
}

MiracNetwork * MiracNetwork::Accept ()
{
    int ch;
    int nonblock = 1;

    ch = accept(handle, NULL, NULL);
    if (ch < 0)
        throw MiracException(errno, "accept()", __FUNCTION__);
    if (ioctl(ch, FIONBIO, &nonblock))
        throw MiracException(errno, "ioctl(FIONBIO)", __FUNCTION__);
    return new MiracNetwork(ch);
}

bool MiracNetwork::Connect (const char *address, const char *service)
{
    int ec = 0;

    if (address && service)
    {
        Close();

        struct addrinfo addr_hint;
        memset(&addr_hint, 0x00, sizeof(addr_hint));
        addr_hint.ai_socktype = SOCK_STREAM;
        ec = getaddrinfo(address, service, &addr_hint,
            reinterpret_cast<struct addrinfo **> (&conn_ares));
        if (ec)
            throw MiracException(gai_strerror(ec), __FUNCTION__);
        conn_aptr = conn_ares;
    }
    else
    {
        socklen_t optlen = sizeof(ec);
        if (getsockopt(handle, SOL_SOCKET, SO_ERROR, &ec, &optlen))
            throw MiracException(errno, "getsockopt()", __FUNCTION__);
        if (!ec)
            return true;
        conn_aptr = reinterpret_cast<struct addrinfo *> (conn_aptr)->ai_next;
    }

    struct addrinfo *addr = reinterpret_cast<struct addrinfo *> (conn_aptr);
    if (!addr)
        throw MiracException("peer unavailable", __FUNCTION__);
    /* note, the SOCK_NONBLOCK is specific to Linux 2.6.27+,
     * on other platforms use either fcntl() or ioctl(h, FIONBIO, 1) */
    handle = socket(addr->ai_family,
        addr->ai_socktype | SOCK_NONBLOCK, addr->ai_protocol);
    if (handle < 0)
        throw MiracException(errno, "socket()", __FUNCTION__);
    if (connect(handle, addr->ai_addr, addr->ai_addrlen))
    {
        if (errno == EINPROGRESS)
            return false;
        throw MiracException(errno, "connect()", __FUNCTION__);
    }
    return true;
}

std::string MiracNetwork::GetPeerAddress ()
{
    int ec;
    socklen_t addrsize = std::max(sizeof(sockaddr_in), sizeof(sockaddr_in6));
    std::unique_ptr<uint8_t []> addrbuf(new uint8_t[addrsize]);
    std::unique_ptr<char []> namebuf(new char [MIRAC_MAX_NAMELEN + 1]);
    std::unique_ptr<char []> servbuf(new char [MIRAC_MAX_NAMELEN + 1]);

    if (getpeername(handle,
        reinterpret_cast<struct sockaddr *> (addrbuf.get()), &addrsize))
        throw MiracException(errno, "getpeername()", __FUNCTION__);
    ec = getnameinfo(
        reinterpret_cast<struct sockaddr *> (addrbuf.get()), addrsize,
        namebuf.get(), MIRAC_MAX_NAMELEN,
        servbuf.get(), MIRAC_MAX_NAMELEN,
        NI_NOFQDN|NI_NUMERICHOST|NI_NUMERICSERV);
    if (ec)
        throw MiracException(gai_strerror(ec), __FUNCTION__);
    return std::string(namebuf.get());
}

unsigned short MiracNetwork::GetHostPort ()
{
    socklen_t addrsize = std::max(sizeof(sockaddr_in), sizeof(sockaddr_in6));
    std::unique_ptr<uint8_t []> addrbuf(new uint8_t[addrsize]);

    if (getsockname(handle,
        reinterpret_cast<struct sockaddr *> (addrbuf.get()), &addrsize))
        throw MiracException(errno, "getsockname()", __FUNCTION__);

    struct sockaddr *saddr =
        reinterpret_cast<struct sockaddr *> (addrbuf.get());
    if (saddr->sa_family == AF_INET)
    {
        struct sockaddr_in *ip4addr =
            reinterpret_cast<struct sockaddr_in *> (saddr);
        return ntohs(ip4addr->sin_port);
    }
    else if (saddr->sa_family == AF_INET6)
    {
        struct sockaddr_in6 *ip6addr =
            reinterpret_cast<struct sockaddr_in6 *> (saddr);
        return ntohs(ip6addr->sin6_port);
    }
    return 0;
}

bool MiracNetwork::Receive (std::string &message)
{
    int ec;
    char nb[page_size];

    do {
        ec = recv(handle, nb, page_size, 0);
        if (ec > 0)
            message.append(nb, ec);
        else if (ec < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                break;
            throw MiracException(errno, "recv()", __FUNCTION__);
        }
        else  // ec == 0
            throw MiracConnectionLostException( __FUNCTION__);
    } while (ec > 0);

    return true;
}

bool MiracNetwork::Receive (std::string &message, size_t length)
{
    int ec;
    char nb[page_size];

    do {
        ec = recv(handle, nb, page_size, 0);
        if (ec > 0)
            recv_buf.append(nb, ec);
        else if (ec < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                break;
            throw MiracException(errno, "recv()", __FUNCTION__);
        }
        else  // ec == 0
            throw MiracConnectionLostException( __FUNCTION__);
    } while (ec > 0);

    if (recv_buf.size() < length)
        return false;

    message = recv_buf.substr(0, length);
    recv_buf.erase(0, length);
    return true;
}

bool MiracNetwork::Send (const std::string &message)
{
    int ec;

    if (!message.empty())
        send_buf.append(message);
    do {
        ec = send(handle, send_buf.c_str(), send_buf.size(), MSG_NOSIGNAL);
        if (ec > 0)
            send_buf.erase(0, ec);
        else
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                return false;
            if (errno == EPIPE || errno == ENOTCONN)
                throw MiracConnectionLostException(__FUNCTION__);
            throw MiracException(errno, "send()", __FUNCTION__);
        }
    } while (send_buf.size() > 0);

    return true;
}

<commit_msg>Handle 'Connection reset by peer' gracefully<commit_after>/*
 * This file is part of Wireless Display Software for Linux OS
 *
 * Copyright (C) 2014 Intel Corporation.
 *
 * Contact: Jussi Laako <jussi.laako@linux.intel.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include <algorithm>
#include <memory>

#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>

#include "mirac-network.hpp"

#define MIRAC_MAX_NAMELEN       255

MiracNetwork::MiracNetwork ()
{
    Init();
}

MiracNetwork::MiracNetwork (int conn_handle)
{
    Init();
    handle = conn_handle;
}

MiracNetwork::~MiracNetwork ()
{
    Close();
}

void MiracNetwork::Init ()
{
    long ps;

    handle = -1;

    ps = sysconf(_SC_PAGESIZE);
    page_size = (ps <= 0) ? 4096 : static_cast<size_t> (ps);

    conn_ares = NULL;
}

void MiracNetwork::Close ()
{
    if (handle >= 0)
        close(handle);
    handle = -1;

    if (conn_ares)
    {
        freeaddrinfo(reinterpret_cast<struct addrinfo *> (conn_ares));
        conn_ares = NULL;
    }
}

void MiracNetwork::Bind (const char *address, const char *service)
{
    int ec;
    int reuse = 1;
    struct addrinfo *addr_res = NULL;
    struct addrinfo *bind_addr;
    struct addrinfo addr_hint;

    Close();

    memset(&addr_hint, 0x00, sizeof(addr_hint));
    addr_hint.ai_flags = AI_PASSIVE;
    ec = getaddrinfo(address, service, &addr_hint, &addr_res);
    if (ec)
        throw MiracException(gai_strerror(ec), __FUNCTION__);
    bind_addr = addr_res;
    while (bind_addr)
    {
        /* note, the SOCK_NONBLOCK is specific to Linux 2.6.27+,
         * on other platforms use either fcntl() or ioctl(h, FIONBIO, 1) */
        handle = socket(addr_res->ai_family,
            addr_res->ai_socktype | SOCK_NONBLOCK, addr_res->ai_protocol);
        if (handle < 0)
            throw MiracException(errno, "socket()", __FUNCTION__);
        if (setsockopt(handle, SOL_SOCKET, SO_REUSEADDR,
            &reuse, sizeof(reuse)))
            throw MiracException(errno, "setsockopt()", __FUNCTION__);
	if (bind(handle, bind_addr->ai_addr, bind_addr->ai_addrlen) == 0)
           break;
        else if (!bind_addr->ai_next)
            throw MiracException(errno, "bind()", __FUNCTION__);
        close(handle);
	bind_addr = bind_addr->ai_next;
    }
    freeaddrinfo(addr_res);

    if (listen(handle, 1))
        throw MiracException(errno, "listen()", __FUNCTION__);
}

MiracNetwork * MiracNetwork::Accept ()
{
    int ch;
    int nonblock = 1;

    ch = accept(handle, NULL, NULL);
    if (ch < 0)
        throw MiracException(errno, "accept()", __FUNCTION__);
    if (ioctl(ch, FIONBIO, &nonblock))
        throw MiracException(errno, "ioctl(FIONBIO)", __FUNCTION__);
    return new MiracNetwork(ch);
}

bool MiracNetwork::Connect (const char *address, const char *service)
{
    int ec = 0;

    if (address && service)
    {
        Close();

        struct addrinfo addr_hint;
        memset(&addr_hint, 0x00, sizeof(addr_hint));
        addr_hint.ai_socktype = SOCK_STREAM;
        ec = getaddrinfo(address, service, &addr_hint,
            reinterpret_cast<struct addrinfo **> (&conn_ares));
        if (ec)
            throw MiracException(gai_strerror(ec), __FUNCTION__);
        conn_aptr = conn_ares;
    }
    else
    {
        socklen_t optlen = sizeof(ec);
        if (getsockopt(handle, SOL_SOCKET, SO_ERROR, &ec, &optlen))
            throw MiracException(errno, "getsockopt()", __FUNCTION__);
        if (!ec)
            return true;
        conn_aptr = reinterpret_cast<struct addrinfo *> (conn_aptr)->ai_next;
    }

    struct addrinfo *addr = reinterpret_cast<struct addrinfo *> (conn_aptr);
    if (!addr)
        throw MiracException("peer unavailable", __FUNCTION__);
    /* note, the SOCK_NONBLOCK is specific to Linux 2.6.27+,
     * on other platforms use either fcntl() or ioctl(h, FIONBIO, 1) */
    handle = socket(addr->ai_family,
        addr->ai_socktype | SOCK_NONBLOCK, addr->ai_protocol);
    if (handle < 0)
        throw MiracException(errno, "socket()", __FUNCTION__);
    if (connect(handle, addr->ai_addr, addr->ai_addrlen))
    {
        if (errno == EINPROGRESS)
            return false;
        throw MiracException(errno, "connect()", __FUNCTION__);
    }
    return true;
}

std::string MiracNetwork::GetPeerAddress ()
{
    int ec;
    socklen_t addrsize = std::max(sizeof(sockaddr_in), sizeof(sockaddr_in6));
    std::unique_ptr<uint8_t []> addrbuf(new uint8_t[addrsize]);
    std::unique_ptr<char []> namebuf(new char [MIRAC_MAX_NAMELEN + 1]);
    std::unique_ptr<char []> servbuf(new char [MIRAC_MAX_NAMELEN + 1]);

    if (getpeername(handle,
        reinterpret_cast<struct sockaddr *> (addrbuf.get()), &addrsize))
        throw MiracException(errno, "getpeername()", __FUNCTION__);
    ec = getnameinfo(
        reinterpret_cast<struct sockaddr *> (addrbuf.get()), addrsize,
        namebuf.get(), MIRAC_MAX_NAMELEN,
        servbuf.get(), MIRAC_MAX_NAMELEN,
        NI_NOFQDN|NI_NUMERICHOST|NI_NUMERICSERV);
    if (ec)
        throw MiracException(gai_strerror(ec), __FUNCTION__);
    return std::string(namebuf.get());
}

unsigned short MiracNetwork::GetHostPort ()
{
    socklen_t addrsize = std::max(sizeof(sockaddr_in), sizeof(sockaddr_in6));
    std::unique_ptr<uint8_t []> addrbuf(new uint8_t[addrsize]);

    if (getsockname(handle,
        reinterpret_cast<struct sockaddr *> (addrbuf.get()), &addrsize))
        throw MiracException(errno, "getsockname()", __FUNCTION__);

    struct sockaddr *saddr =
        reinterpret_cast<struct sockaddr *> (addrbuf.get());
    if (saddr->sa_family == AF_INET)
    {
        struct sockaddr_in *ip4addr =
            reinterpret_cast<struct sockaddr_in *> (saddr);
        return ntohs(ip4addr->sin_port);
    }
    else if (saddr->sa_family == AF_INET6)
    {
        struct sockaddr_in6 *ip6addr =
            reinterpret_cast<struct sockaddr_in6 *> (saddr);
        return ntohs(ip6addr->sin6_port);
    }
    return 0;
}

bool MiracNetwork::Receive (std::string &message)
{
    int ec;
    char nb[page_size];

    do {
        ec = recv(handle, nb, page_size, 0);
        if (ec > 0)
            message.append(nb, ec);
        else if (ec < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                break;
            if (errno == ECONNRESET)
                throw MiracConnectionLostException( __FUNCTION__);
            throw MiracException(errno, "recv()", __FUNCTION__);
        }
        else  // ec == 0
            throw MiracConnectionLostException( __FUNCTION__);
    } while (ec > 0);

    return true;
}

bool MiracNetwork::Receive (std::string &message, size_t length)
{
    int ec;
    char nb[page_size];

    do {
        ec = recv(handle, nb, page_size, 0);
        if (ec > 0)
            recv_buf.append(nb, ec);
        else if (ec < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                break;
            if (errno == ECONNRESET)
                throw MiracConnectionLostException( __FUNCTION__);
            throw MiracException(errno, "recv()", __FUNCTION__);
        }
        else  // ec == 0
            throw MiracConnectionLostException( __FUNCTION__);
    } while (ec > 0);

    if (recv_buf.size() < length)
        return false;

    message = recv_buf.substr(0, length);
    recv_buf.erase(0, length);
    return true;
}

bool MiracNetwork::Send (const std::string &message)
{
    int ec;

    if (!message.empty())
        send_buf.append(message);
    do {
        ec = send(handle, send_buf.c_str(), send_buf.size(), MSG_NOSIGNAL);
        if (ec > 0)
            send_buf.erase(0, ec);
        else
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                return false;
            if (errno == EPIPE || errno == ENOTCONN)
                throw MiracConnectionLostException(__FUNCTION__);
            throw MiracException(errno, "send()", __FUNCTION__);
        }
    } while (send_buf.size() > 0);

    return true;
}

<|endoftext|>