<commit_before>#include "../includes/Scanner.h"
#include "../../Automat/includes/Automat.h"
#include "../../Symboltable/includes/Information.h"
#include <cstring>
#include <iostream>

using namespace std;
Scanner::Scanner(char* argv, char* argv2) {

	if (argv == NULL) {
		argv = "../tests/tryit.txt";
	}

	if (argv2 == NULL) {
		argv2 = "out.txt";
	}

	buffer = new Buffer(argv);
	filedesc = open(argv2, O_WRONLY | O_CREAT|O_TRUNC, 0666);

	symTable = new Symboltable();
	automat = new Automat();
	this->counter = 0;
}

void Scanner::writeInt(long int value, int filedesc){
	char intString[10000];
	int j = 0;
	sprintf(intString, "%ld", value);
	char * pointer = intString;
	while ( *(pointer+j) != '\0') {
		write(filedesc, pointer+j, 1);
		j++;
	}
}

char* Scanner::translateType(int type){

	switch (type) {
		// 1 === Identifier
		case 1:
			translatedType = "Identifier     ";
			break;
		// 2 === Integer
		case 2:
			translatedType = "Integer        ";
			break;
		// 3 === Sign
		case 7:
			translatedType = "PLUS           ";
			break;
		case 14:
			translatedType = "ASSIGNMENT     ";
			break;
		case 15:
			translatedType = "WEIRDTHING     ";
			break;
		case 17:
			translatedType = "ANDAND         ";
			break;
	}

	return translatedType;
}

// returns token
// Token* Scanner::nextToken() {
int Scanner::nextToken() {
	char c;
	int automat_result;
	// Token* t;
	do {
		// Lesen bis zum Lexem
		c = buffer->getChar();
		if (c != '\0' && c != '\n' && c != ' ') {
		// if (c != '\0') {
			// TODO: is this correct?
			counter++;
		}
		automat_result = automat->handle(c);
		// if (automat_result != 0 && automat_result != 20 &&
		// 		automat_result != -99 && automat_result != -1) {
		// 	// TODO: Check if this is a better approach
		// 	counter++;
		// }

		// cout << c;
		// cout << " - automat_result: " << automat_result << " Automat State: " << automat->gettype();
		// cout << '\n';

		// 0 -> checkLexem und Step Back
		// 20 -> checkLexem kein Step Back
		// -1 -> Error Token
		// -99 -> End of File
	} while (automat_result != 0 && automat_result != 20 && automat_result != -1 && automat_result != -99 && automat_result != 24);
	// Wir haben ein Lexem!
	// if (counter == 0) {
		// cout << "Counter is 0";
		// nichts gelesen! Kein Token
		// TODO: if identifier ===> symboletable
		// // TODO: NULL TOKEN
		// t = new Token(automat->gettype(), automat->getline(), automat->getcolumn(), automat->getvalue(), automat->getinformation());;
		// return t;
	// } else {
		switch (automat_result) {
			case 24:
				// cout << "End of Comment \n";
				counter = 0;
				return 1;
				break;
			case 0:
				if (c == '\n' || c == ' ') {
					counter++;
				}
				counter--;
				// automat->decreaseColumn();
				cout << "Token(0): Type: " << automat->gettype() << " Line: " << automat->getline() << " Column: " << automat->getcolumn() - counter << " Counter: " << counter << " raw column: " << automat->getcolumn();
				cout << translateType(automat->gettype());
				cout << '\n';
				write(filedesc, "Token ", 6);
				write(filedesc, translateType(automat->gettype()), 15);
				write(filedesc, " Line: ", 7);
				writeInt(automat->getline(), filedesc);
				write(filedesc, " Column: ", 9);
				writeInt(automat->getcolumn() - counter, filedesc);
				write(filedesc, "\n", 1);

				buffer->stepBack(1);

				if (automat->gettype() == 1) {
					// insert into sym table
					buffer->stepBack(counter);
					char word[counter + 1];
					for (size_t i = 0; i < counter; i++) {
						word[i] = buffer->getChar();
					}
						word[counter] = '\0';
					//  myInformation = new Information(word);
					Information* myInformation = new Information(word);
					// myInformation->printLexem();
					Key* myKey = symTable->insert(myInformation);
					Information* test = symTable->lookup(myKey);
					// test->printLexem();
					// cout << "symTable " << symTable->lookup(myKey);
					// Token* token = new Token(int type, int line, int column, int value, Information* inf);
					Token* token = new Token(automat->gettype(), automat->getline(), automat->getcolumn() - counter, myInformation);
					// cout << token->getLine() << " Token Line \n";
					// cout << token->getTokenTextLength() << "\n";
					// write(filedesc, token->getTokenString(), 9);
				}

				// automat->checkLexem("test");
				counter = 0;
				return 1;
			case 20:
				// counter--;
				cout << "Token(20): Type: " << automat->gettype() << " Line: " << automat->getline() << " Column: " << automat->getcolumn() - counter << " Counter: " << counter << " raw column: " << automat->getcolumn();
				cout << '\n';
				write(filedesc, "Token ", 6);
				write(filedesc, translateType(automat->gettype()), 15);
				write(filedesc, " Line: ", 7);
				writeInt(automat->getline(), filedesc);
				write(filedesc, " Column: ", 9);
				writeInt(automat->getcolumn() - counter, filedesc);
				write(filedesc, "\n", 1);
				counter = 0;
				return 1;
			case -1:
				cout << "Error-Token: Type: " << automat->gettype() << " Line: " << automat->getline() << " Column: " << automat->getcolumn() - counter << " Counter: " << counter << " raw column: " << automat->getcolumn() << c;
				cout << '\n';
				counter = 0;
				return 1;
			case -99:
				cout << "End of File. Exiting...";
				cout << '\n';
				return 0;
			default:
				cout << "Unexpected Error. Exiting...";
				return 0;
		}
	// }
	// t = new Token(automat->gettype(), automat->getline(), automat->getcolumn(), automat->getvalue(), automat->getinformation());;
			// write(filedesc, token.)
	// return t;
}

Scanner::~Scanner() {
	// TODO Auto-generated destructor stub
	close(filedesc);
}
<commit_msg>fixed argv2 bug<commit_after>#include "../includes/Scanner.h"
#include "../../Automat/includes/Automat.h"
#include "../../Symboltable/includes/Information.h"
#include <cstring>
#include <iostream>

using namespace std;
Scanner::Scanner(char* argv, char* argv2) {

	if (argv == NULL) {
		argv = "../tests/tryit.txt";
		argv2 = "out.txt";
	}

	if (argv2 == NULL) {
		argv2 = "out.txt";
	}

	buffer = new Buffer(argv);
	filedesc = open(argv2, O_WRONLY | O_CREAT|O_TRUNC, 0666);

	symTable = new Symboltable();
	automat = new Automat();
	this->counter = 0;
}

void Scanner::writeInt(long int value, int filedesc){
	char intString[10000];
	int j = 0;
	sprintf(intString, "%ld", value);
	char * pointer = intString;
	while ( *(pointer+j) != '\0') {
		write(filedesc, pointer+j, 1);
		j++;
	}
}

char* Scanner::translateType(int type){

	switch (type) {
		// 1 === Identifier
		case 1:
			translatedType = "Identifier     ";
			break;
		// 2 === Integer
		case 2:
			translatedType = "Integer        ";
			break;
		// 3 === Sign
		case 7:
			translatedType = "PLUS           ";
			break;
		case 14:
			translatedType = "ASSIGNMENT     ";
			break;
		case 15:
			translatedType = "WEIRDTHING     ";
			break;
		case 17:
			translatedType = "ANDAND         ";
			break;
	}

	return translatedType;
}

// returns token
// Token* Scanner::nextToken() {
int Scanner::nextToken() {
	char c;
	int automat_result;
	// Token* t;
	do {
		// Lesen bis zum Lexem
		c = buffer->getChar();
		if (c != '\0' && c != '\n' && c != ' ') {
		// if (c != '\0') {
			// TODO: is this correct?
			counter++;
		}
		automat_result = automat->handle(c);
		// if (automat_result != 0 && automat_result != 20 &&
		// 		automat_result != -99 && automat_result != -1) {
		// 	// TODO: Check if this is a better approach
		// 	counter++;
		// }

		// cout << c;
		// cout << " - automat_result: " << automat_result << " Automat State: " << automat->gettype();
		// cout << '\n';

		// 0 -> checkLexem und Step Back
		// 20 -> checkLexem kein Step Back
		// -1 -> Error Token
		// -99 -> End of File
	} while (automat_result != 0 && automat_result != 20 && automat_result != -1 && automat_result != -99 && automat_result != 24);
	// Wir haben ein Lexem!
	// if (counter == 0) {
		// cout << "Counter is 0";
		// nichts gelesen! Kein Token
		// TODO: if identifier ===> symboletable
		// // TODO: NULL TOKEN
		// t = new Token(automat->gettype(), automat->getline(), automat->getcolumn(), automat->getvalue(), automat->getinformation());;
		// return t;
	// } else {
		switch (automat_result) {
			case 24:
				// cout << "End of Comment \n";
				counter = 0;
				return 1;
				break;
			case 0:
				if (c == '\n' || c == ' ') {
					counter++;
				}
				counter--;
				// automat->decreaseColumn();
				cout << "Token(0): Type: " << automat->gettype() << " Line: " << automat->getline() << " Column: " << automat->getcolumn() - counter << " Counter: " << counter << " raw column: " << automat->getcolumn();
				cout << translateType(automat->gettype());
				cout << '\n';
				write(filedesc, "Token ", 6);
				write(filedesc, translateType(automat->gettype()), 15);
				write(filedesc, " Line: ", 7);
				writeInt(automat->getline(), filedesc);
				write(filedesc, " Column: ", 9);
				writeInt(automat->getcolumn() - counter, filedesc);
				write(filedesc, "\n", 1);

				buffer->stepBack(1);

				if (automat->gettype() == 1) {
					// insert into sym table
					buffer->stepBack(counter);
					char word[counter + 1];
					for (size_t i = 0; i < counter; i++) {
						word[i] = buffer->getChar();
					}
						word[counter] = '\0';
					//  myInformation = new Information(word);
					Information* myInformation = new Information(word);
					// myInformation->printLexem();
					Key* myKey = symTable->insert(myInformation);
					Information* test = symTable->lookup(myKey);
					// test->printLexem();
					// cout << "symTable " << symTable->lookup(myKey);
					// Token* token = new Token(int type, int line, int column, int value, Information* inf);
					Token* token = new Token(automat->gettype(), automat->getline(), automat->getcolumn() - counter, myInformation);
					// cout << token->getLine() << " Token Line \n";
					// cout << token->getTokenTextLength() << "\n";
					// write(filedesc, token->getTokenString(), 9);
				}

				// automat->checkLexem("test");
				counter = 0;
				return 1;
			case 20:
				// counter--;
				cout << "Token(20): Type: " << automat->gettype() << " Line: " << automat->getline() << " Column: " << automat->getcolumn() - counter << " Counter: " << counter << " raw column: " << automat->getcolumn();
				cout << '\n';
				write(filedesc, "Token ", 6);
				write(filedesc, translateType(automat->gettype()), 15);
				write(filedesc, " Line: ", 7);
				writeInt(automat->getline(), filedesc);
				write(filedesc, " Column: ", 9);
				writeInt(automat->getcolumn() - counter, filedesc);
				write(filedesc, "\n", 1);
				counter = 0;
				return 1;
			case -1:
				cout << "Error-Token: Type: " << automat->gettype() << " Line: " << automat->getline() << " Column: " << automat->getcolumn() - counter << " Counter: " << counter << " raw column: " << automat->getcolumn() << c;
				cout << '\n';
				counter = 0;
				return 1;
			case -99:
				cout << "End of File. Exiting...";
				cout << '\n';
				return 0;
			default:
				cout << "Unexpected Error. Exiting...";
				return 0;
		}
	// }
	// t = new Token(automat->gettype(), automat->getline(), automat->getcolumn(), automat->getvalue(), automat->getinformation());;
			// write(filedesc, token.)
	// return t;
}

Scanner::~Scanner() {
	// TODO Auto-generated destructor stub
	close(filedesc);
}
<|endoftext|>


<commit_before>// Fill out your copyright notice in the Description page of Project Settings.

#include "CLNR.h"
#include "Cleaner.h"

// Sets default values
ACleaner::ACleaner()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;

	// Configure character movement
	GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
	GetCharacterMovement()->RotationRate = FRotator(0.0f, 480.0f, 0.0f); // ...at this rotation rate
	GetCharacterMovement()->JumpZVelocity = 600.f;
	GetCharacterMovement()->AirControl = 0.2f;
}

// Called when the game starts or when spawned
void ACleaner::BeginPlay()
{
	Super::BeginPlay();
	CurrentGameMode = GetWorld()->GetAuthGameMode<ACLNRGameModeBase>();
	UE_LOG(LogTemp, Warning, TEXT("Power is set to %f"), CurrentGameMode->CurrentPower);
	CurrentGameMode->CurrentPower = CurrentGameMode->MaxPower;
	UE_LOG(LogTemp, Warning, TEXT("Power is set to %f"), CurrentGameMode->CurrentPower);

}

// Called every frame
void ACleaner::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (Interacting)
	{
		CurrentGameMode->ChangePower(DeltaTime * 10 * DrainMultiplier);
	}
	if (MovingX || MovingY)
	{
		CurrentGameMode->ChangePower(DeltaTime);
	}

}

// Called to bind functionality to input
void ACleaner::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	InputComponent->BindAction("Interact", IE_Pressed, this, &ACleaner::InteractPressed);
	InputComponent->BindAction("Interact", IE_Released, this, &ACleaner::InteractReleased);
	InputComponent->BindAction("Kit1", IE_Pressed, this, &ACleaner::Kit1);
	InputComponent->BindAction("Kit2", IE_Pressed, this, &ACleaner::Kit2);
	InputComponent->BindAction("Kit3", IE_Pressed, this, &ACleaner::Kit3);

	InputComponent->BindAxis("Move_X", this, &ACleaner::Move_X);
	InputComponent->BindAxis("Move_Y", this, &ACleaner::Move_Y);

}

void ACleaner::Move_X(float AxisValue)
{
	if ((Controller != NULL) && (AxisValue != 0.0f))
 	{
		// find out which way is forward
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		// get forward vector
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		AddMovementInput(Direction, AxisValue);
		MovingX = true;
	}
	else
		MovingX = false;

}
void ACleaner::Move_Y(float AxisValue)
{
	if ((Controller != NULL) && (AxisValue != 0.0f))
	{
		// find out which way is right
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		// get right vector
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
		// add movement in that direction
		AddMovementInput(Direction, AxisValue);
		MovingY = true;
	}
	else
		MovingY = false;

}
void ACleaner::InteractPressed()
{
	Interacting = true;
	GetCharacterMovement()->MaxWalkSpeed = GetCharacterMovement()->MaxWalkSpeed / 2;
}
void ACleaner::InteractReleased()
{
	Interacting = false;
	GetCharacterMovement()->MaxWalkSpeed = GetCharacterMovement()->MaxWalkSpeed * 2;
}

void ACleaner::Kit1()
{
	if (!Interacting)
	{
		KitNumber = 1;
		DrainMultiplier = 1;
		UE_LOG(LogTemp, Warning, TEXT("Kit set to %i"), KitNumber);
	}

}

void ACleaner::Kit2()
{
	if (!Interacting)
	{
		KitNumber = 2;
		DrainMultiplier = 1.5;
		UE_LOG(LogTemp, Warning, TEXT("Kit set to %i"), KitNumber);
	}

}
void ACleaner::Kit3()
{
	if (!Interacting)
	{
		KitNumber = 3;
		DrainMultiplier = 3;
		UE_LOG(LogTemp, Warning, TEXT("Kit set to %i"), KitNumber);
	}

}

<commit_msg>Added psuedo code for using object(changing kits, emptying)<commit_after>// Fill out your copyright notice in the Description page of Project Settings.

#include "CLNR.h"
#include "Cleaner.h"

// Sets default values
ACleaner::ACleaner()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	bUseControllerRotationPitch = false;
	bUseControllerRotationYaw = false;
	bUseControllerRotationRoll = false;

	// Configure character movement
	GetCharacterMovement()->bOrientRotationToMovement = true; // Character moves in the direction of input...
	GetCharacterMovement()->RotationRate = FRotator(0.0f, 480.0f, 0.0f); // ...at this rotation rate
	GetCharacterMovement()->JumpZVelocity = 600.f;
	GetCharacterMovement()->AirControl = 0.2f;
}

// Called when the game starts or when spawned
void ACleaner::BeginPlay()
{
	Super::BeginPlay();
	CurrentGameMode = GetWorld()->GetAuthGameMode<ACLNRGameModeBase>();
	UE_LOG(LogTemp, Warning, TEXT("Power is set to %f"), CurrentGameMode->CurrentPower);
	CurrentGameMode->CurrentPower = CurrentGameMode->MaxPower;
	UE_LOG(LogTemp, Warning, TEXT("Power is set to %f"), CurrentGameMode->CurrentPower);

}

// Called every frame
void ACleaner::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	if (Interacting)
	{
		CurrentGameMode->ChangePower(DeltaTime * 10 * DrainMultiplier);
	}
	if (MovingX || MovingY)
	{
		CurrentGameMode->ChangePower(DeltaTime);
	}

}

// Called to bind functionality to input
void ACleaner::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);

	InputComponent->BindAction("Interact", IE_Pressed, this, &ACleaner::InteractPressed);
	InputComponent->BindAction("Interact", IE_Released, this, &ACleaner::InteractReleased);
	InputComponent->BindAction("Kit1", IE_Pressed, this, &ACleaner::Kit1);
	InputComponent->BindAction("Kit2", IE_Pressed, this, &ACleaner::Kit2);
	InputComponent->BindAction("Kit3", IE_Pressed, this, &ACleaner::Kit3);

	InputComponent->BindAxis("Move_X", this, &ACleaner::Move_X);
	InputComponent->BindAxis("Move_Y", this, &ACleaner::Move_Y);

}

void ACleaner::Move_X(float AxisValue)
{
	if ((Controller != NULL) && (AxisValue != 0.0f))
 	{
		// find out which way is forward
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		// get forward vector
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
		AddMovementInput(Direction, AxisValue);
		MovingX = true;
	}
	else
		MovingX = false;

}
void ACleaner::Move_Y(float AxisValue)
{
	if ((Controller != NULL) && (AxisValue != 0.0f))
	{
		// find out which way is right
		const FRotator Rotation = Controller->GetControlRotation();
		const FRotator YawRotation(0, Rotation.Yaw, 0);

		// get right vector
		const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
		// add movement in that direction
		AddMovementInput(Direction, AxisValue);
		MovingY = true;
	}
	else
		MovingY = false;

}
void ACleaner::InteractPressed()
{
	Interacting = true;
	GetCharacterMovement()->MaxWalkSpeed = GetCharacterMovement()->MaxWalkSpeed / 2;
}
void ACleaner::InteractReleased()
{
	Interacting = false;
	GetCharacterMovement()->MaxWalkSpeed = GetCharacterMovement()->MaxWalkSpeed * 2;
}

void ACleaner::Kit1()
{
	if (!Interacting)
	{
		KitNumber = 1;
		DrainMultiplier = 1;
		UE_LOG(LogTemp, Warning, TEXT("Kit set to %i"), KitNumber);
	}

}

void ACleaner::Kit2()
{
	if (!Interacting)
	{
		KitNumber = 2;
		DrainMultiplier = 1.5;
		UE_LOG(LogTemp, Warning, TEXT("Kit set to %i"), KitNumber);
	}

}
void ACleaner::Kit3()
{
	if (!Interacting)
	{
		KitNumber = 3;
		DrainMultiplier = 3;
		UE_LOG(LogTemp, Warning, TEXT("Kit set to %i"), KitNumber);
	}

}

/* Psudo-kode for activation av objekter, for  bytte utstyr eller tmme/refille utstyr (som stvsuger pose eller spe)
void Activate()
{
Nr spilleren trykker "E" eller gr i nrheten av et objekt som kan aktiveres, s kjrer den activate funksjonen hos det objektet. Det objektet endrer "kitten"
spilleren bruker eller tmmer/refiller pose eller spe. Dette kan skrives her om det er en knapp som aktiverer det eller kan skrives direkte inn i objektene selv, polymorfi?
Selve sppeltmmingen eller spe innhold kan kodes inn i GameModBase slik at det kan lettere vises i HUD og for at det blir lettere for alle objektene  f tak idet.
}
*/

<|endoftext|>


<commit_before>/*
** Copyright 2009-2011 Merethis
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <assert.h>
#include <stdlib.h>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/logging/file.hh"

using namespace com::centreon::broker::logging;

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Copy constructor.
 *
 *  @param[in] f Unused.
 */
file::file(file const& f) : ostream(f) {
  (void)f;
  assert(false);
  abort();
}

/**
 *  Assignment operator.
 *
 *  @param[in] f Unused.
 *
 *  @return This object.
 */
file& file::operator=(file const& f) {
  (void)f;
  assert(false);
  abort();
  return (*this);
}

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
file::file() {}

/**
 *  Constructor.
 *
 *  @param[in] filename Name of the file to open.
 */
file::file(char const* filename) {
  open(filename);
}

/**
 *  Destructor.
 */
file::~file() {}

/**
 *  Open a log file.
 *
 *  @param[in] filename Name of the file to open.
 */
void file::open(char const* filename) {
  // Check filename is not NULL.
  if (!filename)
    throw (exceptions::msg() << "trying to open NULL log file");

  // Close file if previously opened.
  if (_ofs.is_open())
    _ofs.close();

  // Open file.
  _ofs.open(filename, std::ios_base::out
                      | std::ios_base::app
                      | std::ios_base::ate);
  if (_ofs.fail())
    throw (exceptions::msg() << "could not open \""
                             << filename << "\" log file");

  // Don't forget to set the stream to write on.
  ostream::operator=(_ofs);

  // Opening message.
  _ofs << "Centreon Broker log file successfully opened";

  return ;
}
<commit_msg>Fix log opening message.<commit_after>/*
** Copyright 2009-2011 Merethis
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker 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
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include <assert.h>
#include <stdlib.h>
#include "com/centreon/broker/exceptions/msg.hh"
#include "com/centreon/broker/logging/file.hh"

using namespace com::centreon::broker::logging;

/**************************************
*                                     *
*           Private Methods           *
*                                     *
**************************************/

/**
 *  Copy constructor.
 *
 *  @param[in] f Unused.
 */
file::file(file const& f) : ostream(f) {
  (void)f;
  assert(false);
  abort();
}

/**
 *  Assignment operator.
 *
 *  @param[in] f Unused.
 *
 *  @return This object.
 */
file& file::operator=(file const& f) {
  (void)f;
  assert(false);
  abort();
  return (*this);
}

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Default constructor.
 */
file::file() {}

/**
 *  Constructor.
 *
 *  @param[in] filename Name of the file to open.
 */
file::file(char const* filename) {
  open(filename);
}

/**
 *  Destructor.
 */
file::~file() {}

/**
 *  Open a log file.
 *
 *  @param[in] filename Name of the file to open.
 */
void file::open(char const* filename) {
  // Check filename is not NULL.
  if (!filename)
    throw (exceptions::msg() << "trying to open NULL log file");

  // Close file if previously opened.
  if (_ofs.is_open())
    _ofs.close();

  // Open file.
  _ofs.open(filename, std::ios_base::out
                      | std::ios_base::app
                      | std::ios_base::ate);
  if (_ofs.fail())
    throw (exceptions::msg() << "could not open \""
                             << filename << "\" log file");

  // Don't forget to set the stream to write on.
  ostream::operator=(_ofs);

  // Opening message.
  _ofs << "Centreon Broker log file successfully opened\n";

  return ;
}
<|endoftext|>


<commit_before>#include <QStringList>
#include "kernel_global.h"
#include "ilwis.h"
#include "geos/geom/Coordinate.h"
#ifdef Q_OS_WIN
#include "geos/geom/Coordinate.inl"
#endif
#include "coordinate.h"
#include <cmath>

using namespace Ilwis;

const double crdDeltaLim = 1e-8;

Ilwis::Coordinate::Coordinate() : geos::geom::Coordinate(rUNDEF, rUNDEF, rUNDEF)
{
}

Ilwis::Coordinate::Coordinate(const geos::geom::Coordinate& crd) : geos::geom::Coordinate(crd){
    if (std::isnan(this->z))
        this->z = rUNDEF;
}

Ilwis::Coordinate::Coordinate(const Ilwis::Coordinate& crd) : geos::geom::Coordinate(crd.x,crd.y,crd.z){

}

Ilwis::Coordinate::Coordinate(double px, double py, double pz) : geos::geom::Coordinate(px,py,pz){
}

Ilwis::Coordinate::Coordinate(const std::vector<double>& v)  {
    if ( v.size() < 2) {
        *this = Ilwis::Coordinate();
        return;
    }
    this->x =v[0];
    this->y =v[1];
    if ( v.size() >= 3)
        this->z = v[2];

 }

Ilwis::Coordinate::~Coordinate() {
}

/*!
 a point is valid if both its x and y have a valid value;
 * \return
 */
bool Ilwis::Coordinate::isValid() const{
    return x != undefined() && y != undefined() ;
}

bool Ilwis::Coordinate::is0() const{
    return x == 0 && y == 0 ;
}

bool Ilwis::Coordinate::is3D() const {
    if (!isValid())
        return false;
    return z != undefined();
}

Ilwis::Coordinate::operator std::vector<double> () {

    std::vector<double> v;
    if ( !isValid())
        return v;

    if ( is3D()) {
         v = {this->x, this->y, this->z};
        return v;
    }
    v = {this->x, this->y};
    return v;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Ilwis::Coordinate& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Coordinate&& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

/*!
 operator += addes a vector of 2 values to a point shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Coordinate& Ilwis::Coordinate::operator+= (const std::vector<double> &vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }

    this->x =this->x + vec[0];
    this->y =this->y + vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z + vec[2];

    return *this;
}

Coordinate& Ilwis::Coordinate::operator-= (const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x - vec[0];
    this->y =this->y - vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z - vec[2];

    return *this;
}

double Ilwis::Coordinate::distance(const Coordinate& crd) {
    if ( !crd.isValid() || !this->isValid())
        return this->undefined();
    if ( z == undefined() || crd.z == undefined())
        return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2));
    return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2) + std::pow(abs(this->z - crd.z),2));
}

/*!
 operator *= multiplies a point with a factor contained in the vector, shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param  a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * vec[0];
    this->y =this->y * vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z * vec[2];

    return *this;
}

/*!
 operator *= multipliesthe x,y values with a single factor , shifting it in 2D space. Using undefined() values may lead to unpredictable results
 * \param  multiplier
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(double v){
    if (!this->isValid()){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * v;
    this->y =this->y * v;
    if ( z != undefined())
        this->z =this->z * v;

    return *this;
}

/*!
 operator /= divides the coordinates of a point with a fixed value. The value must not be zero. If it is zero nothing happens
 Using undefined() values may lead to unpredictable results
 * \param v
 * \return
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator/=(double v){
    if (!this->isValid() || v == 0){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x / v;
    this->y =this->y / v;
    if ( z != undefined())
        this->z =this->z / v;

    return *this;
}

/*!
 compares the coordinates of 2 points to see if they are equal. comparision with non valid points always leads to false
 * \param pnt, point to be compared
 * \return true if the points are at the same Coordinate.
 */
bool Ilwis::Coordinate::operator==(const Ilwis::Coordinate& pnt) const {
    if ( !pnt.isValid() && !this->isValid())
        return true;

    if (!this->isValid() || !pnt.isValid())
        return false;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && (std::abs(pnt.z - this->z)<crdDeltaLim);
}

bool Coordinate::operator ==(const geos::geom::Coordinate &pnt) const{
    if (!this->isValid() && (pnt.x == rUNDEF || pnt.y == rUNDEF || std::isnan(pnt.x) || std::isnan(pnt.y)))
        return true;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && ((std::abs(pnt.z - this->z)<crdDeltaLim) || (std::isnan(pnt.z) && this->z == rUNDEF));
}
/*!
 compares the coordinates of 2 points to see if they are not equal. comparision with non valid points always leads to true
 * \param pnt, point to be compared
 * \return true if the points are not at the same Coordinate.
 */
bool Ilwis::Coordinate::operator!=(const Ilwis::Coordinate& pnt){
    return !(operator==(pnt));
}

Coordinate& Coordinate::operator =(const geos::geom::Coordinate& crd){
    this->x = crd.x;
    this->y = crd.y;
    if (std::isnan(crd.z))
        this->z = rUNDEF;
    else
        this->z = crd.z;
    return *this;
}

//-----------------------------------------------
std::vector<double> Ilwis::operator-(const Ilwis::Coordinate& p1, const Ilwis::Coordinate& p2) {
    if (!(p1.isValid() && p2.isValid()))
        return std::vector<double>();
    std::vector<double> v(3,0);
    v[0] = p1.x - p2.x;
    v[1] = p1.y - p2.y ;
    if ( p1.z != p1.undefined() && p2.z != p2.undefined())
        v[2] = p1.z - p2.z ;
    return v;
}

Ilwis::Coordinate Ilwis::operator+(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x + vec[0];
    p3.y = p1.y + vec[1] ;
    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z + vec[2];

    return p3;
}

Ilwis::Coordinate Ilwis::operator-(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x - vec[0];
    p3.y = p1.y - vec[1] ;

    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z - vec[2];
    return p3;
}

Ilwis::Coordinate Ilwis::operator*(const Ilwis::Coordinate& p1, double v) {
    if (p1.isValid() == false || v == rUNDEF )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x * v;
    p3.y = p1.y * v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z * v;
    return p3;
}

Ilwis::Coordinate Ilwis::operator/(const Ilwis::Coordinate& p1, double v) {
    if (!p1.isValid() || v == 0)
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x / v;
    p3.y = p1.y / v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z / v;
    return p3;
}

//---------------------------------------------------------------------------
LatLon::LatLon(){

}

LatLon::LatLon(const Angle &latd, const Angle &lond, double h){
    lat(latd);
    lon(lond);
    z= h;
}

LatLon::LatLon(const QString &lat, const QString &lon)
{
    auto func = [] ( QString value) -> double {
        bool ok = true;
        value = value.trimmed();
        double sign = 1.0;
        if ( value.right(1) == "S"){
            sign = -1.0;
        }else if ( value.right(1) == "W") {
            sign = -1.0;
        }
        value.right(1).toLong(&ok);
        if ( !ok)
            value = value.left(value.size() -2);
        QStringList parts = value.split(" ");
        double v  = parts[0].toDouble(&ok);
        if ( ok && parts.size() > 1) {
            v += parts[1].toDouble(&ok) / 60.0;
            if ( ok && parts.size() == 3){
                v += parts[2].toDouble(&ok)/ (60.0 * 60.0);
            }
        }
        if ( ok)
            return sign * v;
        return rUNDEF;
    };
    y = func( lat);
    x = func( lon);
    if ( x == rUNDEF || y == rUNDEF)
        x = y = rUNDEF;
}

Angle LatLon::lat() const{
    return y;
}
Angle LatLon::lon() const{
    return x;
}

void LatLon::lat(const Angle& val){
    y = val.degrees();
}

void LatLon::lon(const Angle& val){
    x = val.degrees();
}
<commit_msg>improved parsing of string versions of latlon<commit_after>#include <QStringList>
#include "kernel_global.h"
#include "ilwis.h"
#include "geos/geom/Coordinate.h"
#ifdef Q_OS_WIN
#include "geos/geom/Coordinate.inl"
#endif
#include "coordinate.h"
#include <cmath>

using namespace Ilwis;

const double crdDeltaLim = 1e-8;

Ilwis::Coordinate::Coordinate() : geos::geom::Coordinate(rUNDEF, rUNDEF, rUNDEF)
{
}

Ilwis::Coordinate::Coordinate(const geos::geom::Coordinate& crd) : geos::geom::Coordinate(crd){
    if (std::isnan(this->z))
        this->z = rUNDEF;
}

Ilwis::Coordinate::Coordinate(const Ilwis::Coordinate& crd) : geos::geom::Coordinate(crd.x,crd.y,crd.z){

}

Ilwis::Coordinate::Coordinate(double px, double py, double pz) : geos::geom::Coordinate(px,py,pz){
}

Ilwis::Coordinate::Coordinate(const std::vector<double>& v)  {
    if ( v.size() < 2) {
        *this = Ilwis::Coordinate();
        return;
    }
    this->x =v[0];
    this->y =v[1];
    if ( v.size() >= 3)
        this->z = v[2];

 }

Ilwis::Coordinate::~Coordinate() {
}

/*!
 a point is valid if both its x and y have a valid value;
 * \return
 */
bool Ilwis::Coordinate::isValid() const{
    return x != undefined() && y != undefined() ;
}

bool Ilwis::Coordinate::is0() const{
    return x == 0 && y == 0 ;
}

bool Ilwis::Coordinate::is3D() const {
    if (!isValid())
        return false;
    return z != undefined();
}

Ilwis::Coordinate::operator std::vector<double> () {

    std::vector<double> v;
    if ( !isValid())
        return v;

    if ( is3D()) {
         v = {this->x, this->y, this->z};
        return v;
    }
    v = {this->x, this->y};
    return v;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Ilwis::Coordinate& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Coordinate&& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

/*!
 operator += addes a vector of 2 values to a point shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Coordinate& Ilwis::Coordinate::operator+= (const std::vector<double> &vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }

    this->x =this->x + vec[0];
    this->y =this->y + vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z + vec[2];

    return *this;
}

Coordinate& Ilwis::Coordinate::operator-= (const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x - vec[0];
    this->y =this->y - vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z - vec[2];

    return *this;
}

double Ilwis::Coordinate::distance(const Coordinate& crd) {
    if ( !crd.isValid() || !this->isValid())
        return this->undefined();
    if ( z == undefined() || crd.z == undefined())
        return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2));
    return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2) + std::pow(abs(this->z - crd.z),2));
}

/*!
 operator *= multiplies a point with a factor contained in the vector, shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param  a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * vec[0];
    this->y =this->y * vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z * vec[2];

    return *this;
}

/*!
 operator *= multipliesthe x,y values with a single factor , shifting it in 2D space. Using undefined() values may lead to unpredictable results
 * \param  multiplier
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(double v){
    if (!this->isValid()){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * v;
    this->y =this->y * v;
    if ( z != undefined())
        this->z =this->z * v;

    return *this;
}

/*!
 operator /= divides the coordinates of a point with a fixed value. The value must not be zero. If it is zero nothing happens
 Using undefined() values may lead to unpredictable results
 * \param v
 * \return
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator/=(double v){
    if (!this->isValid() || v == 0){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x / v;
    this->y =this->y / v;
    if ( z != undefined())
        this->z =this->z / v;

    return *this;
}

/*!
 compares the coordinates of 2 points to see if they are equal. comparision with non valid points always leads to false
 * \param pnt, point to be compared
 * \return true if the points are at the same Coordinate.
 */
bool Ilwis::Coordinate::operator==(const Ilwis::Coordinate& pnt) const {
    if ( !pnt.isValid() && !this->isValid())
        return true;

    if (!this->isValid() || !pnt.isValid())
        return false;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && (std::abs(pnt.z - this->z)<crdDeltaLim);
}

bool Coordinate::operator ==(const geos::geom::Coordinate &pnt) const{
    if (!this->isValid() && (pnt.x == rUNDEF || pnt.y == rUNDEF || std::isnan(pnt.x) || std::isnan(pnt.y)))
        return true;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && ((std::abs(pnt.z - this->z)<crdDeltaLim) || (std::isnan(pnt.z) && this->z == rUNDEF));
}
/*!
 compares the coordinates of 2 points to see if they are not equal. comparision with non valid points always leads to true
 * \param pnt, point to be compared
 * \return true if the points are not at the same Coordinate.
 */
bool Ilwis::Coordinate::operator!=(const Ilwis::Coordinate& pnt){
    return !(operator==(pnt));
}

Coordinate& Coordinate::operator =(const geos::geom::Coordinate& crd){
    this->x = crd.x;
    this->y = crd.y;
    if (std::isnan(crd.z))
        this->z = rUNDEF;
    else
        this->z = crd.z;
    return *this;
}

//-----------------------------------------------
std::vector<double> Ilwis::operator-(const Ilwis::Coordinate& p1, const Ilwis::Coordinate& p2) {
    if (!(p1.isValid() && p2.isValid()))
        return std::vector<double>();
    std::vector<double> v(3,0);
    v[0] = p1.x - p2.x;
    v[1] = p1.y - p2.y ;
    if ( p1.z != p1.undefined() && p2.z != p2.undefined())
        v[2] = p1.z - p2.z ;
    return v;
}

Ilwis::Coordinate Ilwis::operator+(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x + vec[0];
    p3.y = p1.y + vec[1] ;
    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z + vec[2];

    return p3;
}

Ilwis::Coordinate Ilwis::operator-(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x - vec[0];
    p3.y = p1.y - vec[1] ;

    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z - vec[2];
    return p3;
}

Ilwis::Coordinate Ilwis::operator*(const Ilwis::Coordinate& p1, double v) {
    if (p1.isValid() == false || v == rUNDEF )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x * v;
    p3.y = p1.y * v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z * v;
    return p3;
}

Ilwis::Coordinate Ilwis::operator/(const Ilwis::Coordinate& p1, double v) {
    if (!p1.isValid() || v == 0)
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x / v;
    p3.y = p1.y / v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z / v;
    return p3;
}

//---------------------------------------------------------------------------
LatLon::LatLon(){

}

LatLon::LatLon(const Angle &latd, const Angle &lond, double h){
    lat(latd);
    lon(lond);
    z= h;
}

LatLon::LatLon(const QString &lat, const QString &lon)
{
    auto func = [] ( QString value) -> double {
        bool ok;
        double v =  value.toDouble(&ok);
        if ( ok) // we were already a decimal variant; no further parsing needed
            return v;
        value = value.trimmed();
        double sign = 1.0;
        if ( value.right(1) == "S"){
            sign = -1.0;
        }else if ( value.right(1) == "W") {
            sign = -1.0;
        }
        value.right(1).toLong(&ok);
        if ( !ok)
            value = value.left(value.size() -2);
        QStringList parts = value.split(" ");
        v  = parts[0].toDouble(&ok);
        if ( ok && parts.size() > 1) {
            v += parts[1].toDouble(&ok) / 60.0;
            if ( ok && parts.size() == 3){
                v += parts[2].toDouble(&ok)/ 3600.0;
            }
        }
        if ( ok)
            return sign * v;
        return rUNDEF;
    };
    y = func( lat);
    x = func( lon);
    if ( x == rUNDEF || y == rUNDEF)
        x = y = rUNDEF;
}

Angle LatLon::lat() const{
    return y;
}
Angle LatLon::lon() const{
    return x;
}

void LatLon::lat(const Angle& val){
    y = val.degrees();
}

void LatLon::lon(const Angle& val){
    x = val.degrees();
}
<|endoftext|>


<commit_before>#include <QStringList>
#include <QVector3D>
#include "kernel_global.h"
#include "ilwis.h"
#include "geos/geom/Coordinate.h"
#ifdef Q_OS_WIN
#include "geos/geom/Coordinate.inl"
#endif
#include "coordinate.h"
#include <cmath>

using namespace Ilwis;

const double crdDeltaLim = 1e-8;

Ilwis::Coordinate::Coordinate() : geos::geom::Coordinate(rUNDEF, rUNDEF, rUNDEF)
{
}

Ilwis::Coordinate::Coordinate(const geos::geom::Coordinate& crd) : geos::geom::Coordinate(crd){
    if (std::isnan(this->z))
        this->z = rUNDEF;
}

Ilwis::Coordinate::Coordinate(const Ilwis::Coordinate& crd) : geos::geom::Coordinate(crd.x,crd.y,crd.z){

}

Ilwis::Coordinate::Coordinate(double px, double py, double pz) : geos::geom::Coordinate(px,py,pz){
}

Ilwis::Coordinate::Coordinate(const std::vector<double>& v)  {
    if ( v.size() < 2) {
        *this = Ilwis::Coordinate();
        return;
    }
    this->x =v[0];
    this->y =v[1];
    if ( v.size() >= 3)
        this->z = v[2];

}

Coordinate::Coordinate(const QVector3D &crd)
{
    x = crd.x();
    y = crd.y();
    z = crd.z();
}

Ilwis::Coordinate::~Coordinate() {
}

/*!
 a point is valid if both its x and y have a valid value;
 * \return
 */
bool Ilwis::Coordinate::isValid() const{
    return x != undefined() && y != undefined() ;
}

bool Ilwis::Coordinate::is0() const{
    return x == 0 && y == 0 ;
}

bool Ilwis::Coordinate::is3D() const {
    if (!isValid())
        return false;
    return z != undefined();
}

Ilwis::Coordinate::operator std::vector<double> () {

    std::vector<double> v;
    if ( !isValid())
        return v;

    if ( is3D()) {
         v = {this->x, this->y, this->z};
        return v;
    }
    v = {this->x, this->y};
    return v;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Ilwis::Coordinate& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Coordinate&& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

/*!
 operator += addes a vector of 2 values to a point shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Coordinate& Ilwis::Coordinate::operator+= (const std::vector<double> &vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }

    this->x =this->x + vec[0];
    this->y =this->y + vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z + vec[2];

    return *this;
}

Coordinate& Ilwis::Coordinate::operator-= (const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x - vec[0];
    this->y =this->y - vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z - vec[2];

    return *this;
}

double Ilwis::Coordinate::distance(const Coordinate& crd) {
    if ( !crd.isValid() || !this->isValid())
        return this->undefined();
    if ( z == undefined() || crd.z == undefined())
        return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2));
    return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2) + std::pow(abs(this->z - crd.z),2));
}

/*!
 operator *= multiplies a point with a factor contained in the vector, shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param  a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * vec[0];
    this->y =this->y * vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z * vec[2];

    return *this;
}

/*!
 operator *= multipliesthe x,y values with a single factor , shifting it in 2D space. Using undefined() values may lead to unpredictable results
 * \param  multiplier
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(double v){
    if (!this->isValid()){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * v;
    this->y =this->y * v;
    if ( z != undefined())
        this->z =this->z * v;

    return *this;
}

/*!
 operator /= divides the coordinates of a point with a fixed value. The value must not be zero. If it is zero nothing happens
 Using undefined() values may lead to unpredictable results
 * \param v
 * \return
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator/=(double v){
    if (!this->isValid() || v == 0){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x / v;
    this->y =this->y / v;
    if ( z != undefined())
        this->z =this->z / v;

    return *this;
}

/*!
 compares the coordinates of 2 points to see if they are equal. comparision with non valid points always leads to false
 * \param pnt, point to be compared
 * \return true if the points are at the same Coordinate.
 */
bool Ilwis::Coordinate::operator==(const Ilwis::Coordinate& pnt) const {
    if ( !pnt.isValid() && !this->isValid())
        return true;

    if (!this->isValid() || !pnt.isValid())
        return false;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && (std::abs(pnt.z - this->z)<crdDeltaLim);
}

bool Coordinate::operator ==(const geos::geom::Coordinate &pnt) const{
    if (!this->isValid() && (pnt.x == rUNDEF || pnt.y == rUNDEF || std::isnan(pnt.x) || std::isnan(pnt.y)))
        return true;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && ((std::abs(pnt.z - this->z)<crdDeltaLim) || (std::isnan(pnt.z) && this->z == rUNDEF));
}
/*!
 compares the coordinates of 2 points to see if they are not equal. comparision with non valid points always leads to true
 * \param pnt, point to be compared
 * \return true if the points are not at the same Coordinate.
 */
bool Ilwis::Coordinate::operator!=(const Ilwis::Coordinate& pnt){
    return !(operator==(pnt));
}

QString Coordinate::toString(int decimals, bool use3D) const
{
    if ( !isValid())
        return "";

    if( use3D)   {
        return QString("%1 %2").arg(x,0,'f', decimals).arg(y,0,'f', decimals).arg(z,0,'f', decimals);
    }
    return QString("%1 %2").arg(x,0,'f', decimals).arg(y,0,'f', decimals);
}

Coordinate& Coordinate::operator =(const geos::geom::Coordinate& crd){
    this->x = crd.x;
    this->y = crd.y;
    if (std::isnan(crd.z))
        this->z = rUNDEF;
    else
        this->z = crd.z;
    return *this;
}

Coordinate &Coordinate::operator =(const QVector3D &p2)
{
    this->x = p2.x();
    this->y = p2.y();
    this->z = p2.z();

    return *this;
}

//-----------------------------------------------
std::vector<double> Ilwis::operator-(const Ilwis::Coordinate& p1, const Ilwis::Coordinate& p2) {
    if (!(p1.isValid() && p2.isValid()))
        return std::vector<double>();
    std::vector<double> v(3,0);
    v[0] = p1.x - p2.x;
    v[1] = p1.y - p2.y ;
    if ( p1.z != p1.undefined() && p2.z != p2.undefined())
        v[2] = p1.z - p2.z ;
    return v;
}

Ilwis::Coordinate Ilwis::operator+(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x + vec[0];
    p3.y = p1.y + vec[1] ;
    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z + vec[2];

    return p3;
}

Ilwis::Coordinate Ilwis::operator-(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x - vec[0];
    p3.y = p1.y - vec[1] ;

    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z - vec[2];
    return p3;
}

Ilwis::Coordinate Ilwis::operator*(const Ilwis::Coordinate& p1, double v) {
    if (p1.isValid() == false || v == rUNDEF )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x * v;
    p3.y = p1.y * v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z * v;
    return p3;
}

Ilwis::Coordinate Ilwis::operator/(const Ilwis::Coordinate& p1, double v) {
    if (!p1.isValid() || v == 0)
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x / v;
    p3.y = p1.y / v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z / v;
    return p3;
}

//---------------------------------------------------------------------------
LatLon::LatLon(){

}

LatLon::LatLon(const Angle &latd, const Angle &lond, double h){
    lat(latd);
    lon(lond);
    z= h;
}

LatLon::LatLon(const QString &lat, const QString &lon)
{
    auto func = [] ( QString value) -> double {
        bool ok;
        double v =  value.toDouble(&ok);
        if ( ok) // we were already a decimal variant; no further parsing needed
            return v;
        value = value.trimmed();
        double sign = 1.0;
        if ( value.right(1) == "S"){
            sign = -1.0;
        }else if ( value.right(1) == "W") {
            sign = -1.0;
        }
        value.right(1).toLong(&ok);
        if ( !ok)
            value = value.left(value.size() -2);
        QStringList parts = value.split(" ");
        v  = parts[0].toDouble(&ok);
        if ( ok && parts.size() > 1) {
            v += parts[1].toDouble(&ok) / 60.0;
            if ( ok && parts.size() == 3){
                v += parts[2].toDouble(&ok)/ 3600.0;
            }
        }
        if ( ok)
            return sign * v;
        return rUNDEF;
    };
    y = func( lat);
    x = func( lon);
    if ( x == rUNDEF || y == rUNDEF)
        x = y = rUNDEF;
}

Angle LatLon::lat() const{
    return y;
}
Angle LatLon::lon() const{
    return x;
}

void LatLon::lat(const Angle& val){
    y = val.degrees();
}

void LatLon::lon(const Angle& val){
    x = val.degrees();
}

QString LatLon::toString(int decimals, bool ) const
{
    if ( !isValid())
        return "";

    auto ll = [&](double loc) -> QString {
        const QChar chardgr(0260);
        int dgr = std::abs((int)loc);
        int dmin = (std::abs(loc) - dgr) * 60;
        double dsec = (std::abs(loc) -  dgr - dmin/60.0) * 60.0;
        dgr = loc < 0 ? -dgr : dgr;

        QString result = QString("%1%2 %3\' %4\'\'").arg(dgr).arg(chardgr).arg(dmin).arg(dsec,0,'f', decimals);
        return result;
    };
    QString llstring = QString("%1 %2").arg(ll(x)).arg(ll(y));

    return llstring;
}
<commit_msg>latlon was realy lonlat<commit_after>#include <QStringList>
#include <QVector3D>
#include "kernel_global.h"
#include "ilwis.h"
#include "geos/geom/Coordinate.h"
#ifdef Q_OS_WIN
#include "geos/geom/Coordinate.inl"
#endif
#include "coordinate.h"
#include <cmath>

using namespace Ilwis;

const double crdDeltaLim = 1e-8;

Ilwis::Coordinate::Coordinate() : geos::geom::Coordinate(rUNDEF, rUNDEF, rUNDEF)
{
}

Ilwis::Coordinate::Coordinate(const geos::geom::Coordinate& crd) : geos::geom::Coordinate(crd){
    if (std::isnan(this->z))
        this->z = rUNDEF;
}

Ilwis::Coordinate::Coordinate(const Ilwis::Coordinate& crd) : geos::geom::Coordinate(crd.x,crd.y,crd.z){

}

Ilwis::Coordinate::Coordinate(double px, double py, double pz) : geos::geom::Coordinate(px,py,pz){
}

Ilwis::Coordinate::Coordinate(const std::vector<double>& v)  {
    if ( v.size() < 2) {
        *this = Ilwis::Coordinate();
        return;
    }
    this->x =v[0];
    this->y =v[1];
    if ( v.size() >= 3)
        this->z = v[2];

}

Coordinate::Coordinate(const QVector3D &crd)
{
    x = crd.x();
    y = crd.y();
    z = crd.z();
}

Ilwis::Coordinate::~Coordinate() {
}

/*!
 a point is valid if both its x and y have a valid value;
 * \return
 */
bool Ilwis::Coordinate::isValid() const{
    return x != undefined() && y != undefined() ;
}

bool Ilwis::Coordinate::is0() const{
    return x == 0 && y == 0 ;
}

bool Ilwis::Coordinate::is3D() const {
    if (!isValid())
        return false;
    return z != undefined();
}

Ilwis::Coordinate::operator std::vector<double> () {

    std::vector<double> v;
    if ( !isValid())
        return v;

    if ( is3D()) {
         v = {this->x, this->y, this->z};
        return v;
    }
    v = {this->x, this->y};
    return v;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Ilwis::Coordinate& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

Ilwis::Coordinate& Ilwis::Coordinate::operator=(const Coordinate&& p2) {
    this->x = p2.x;
    this->y = p2.y;
    this->z = p2.z;
    return *this;
}

/*!
 operator += addes a vector of 2 values to a point shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Coordinate& Ilwis::Coordinate::operator+= (const std::vector<double> &vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }

    this->x =this->x + vec[0];
    this->y =this->y + vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z + vec[2];

    return *this;
}

Coordinate& Ilwis::Coordinate::operator-= (const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x - vec[0];
    this->y =this->y - vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z - vec[2];

    return *this;
}

double Ilwis::Coordinate::distance(const Coordinate& crd) {
    if ( !crd.isValid() || !this->isValid())
        return this->undefined();
    if ( z == undefined() || crd.z == undefined())
        return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2));
    return std::sqrt(std::pow(abs(this->x - crd.x),2) + std::pow(abs(this->y - crd.y),2) + std::pow(abs(this->z - crd.z),2));
}

/*!
 operator *= multiplies a point with a factor contained in the vector, shifting it in 2D space. Using undefined() values in the vector may lead to unpredictable results
 * \param  a vector with a pair of values
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(const std::vector<double>& vec){
    if (!this->isValid() || vec.size() < 2){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * vec[0];
    this->y =this->y * vec[1];
    if ( vec.size() >= 3 && z != undefined())
        this->z =this->z * vec[2];

    return *this;
}

/*!
 operator *= multipliesthe x,y values with a single factor , shifting it in 2D space. Using undefined() values may lead to unpredictable results
 * \param  multiplier
 * \return a reference to a shifted 2D point
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator*=(double v){
    if (!this->isValid()){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x * v;
    this->y =this->y * v;
    if ( z != undefined())
        this->z =this->z * v;

    return *this;
}

/*!
 operator /= divides the coordinates of a point with a fixed value. The value must not be zero. If it is zero nothing happens
 Using undefined() values may lead to unpredictable results
 * \param v
 * \return
 */
Ilwis::Coordinate& Ilwis::Coordinate::operator/=(double v){
    if (!this->isValid() || v == 0){
        *this = Ilwis::Coordinate();
        return *this;
    }
    this->x =this->x / v;
    this->y =this->y / v;
    if ( z != undefined())
        this->z =this->z / v;

    return *this;
}

/*!
 compares the coordinates of 2 points to see if they are equal. comparision with non valid points always leads to false
 * \param pnt, point to be compared
 * \return true if the points are at the same Coordinate.
 */
bool Ilwis::Coordinate::operator==(const Ilwis::Coordinate& pnt) const {
    if ( !pnt.isValid() && !this->isValid())
        return true;

    if (!this->isValid() || !pnt.isValid())
        return false;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && (std::abs(pnt.z - this->z)<crdDeltaLim);
}

bool Coordinate::operator ==(const geos::geom::Coordinate &pnt) const{
    if (!this->isValid() && (pnt.x == rUNDEF || pnt.y == rUNDEF || std::isnan(pnt.x) || std::isnan(pnt.y)))
        return true;

    return (std::abs(pnt.x -  this->x) < crdDeltaLim) && (std::abs(pnt.y - this->y) < crdDeltaLim) && ((std::abs(pnt.z - this->z)<crdDeltaLim) || (std::isnan(pnt.z) && this->z == rUNDEF));
}
/*!
 compares the coordinates of 2 points to see if they are not equal. comparision with non valid points always leads to true
 * \param pnt, point to be compared
 * \return true if the points are not at the same Coordinate.
 */
bool Ilwis::Coordinate::operator!=(const Ilwis::Coordinate& pnt){
    return !(operator==(pnt));
}

QString Coordinate::toString(int decimals, bool use3D) const
{
    if ( !isValid())
        return "";

    if( use3D)   {
        return QString("%1 %2").arg(x,0,'f', decimals).arg(y,0,'f', decimals).arg(z,0,'f', decimals);
    }
    return QString("%1 %2").arg(x,0,'f', decimals).arg(y,0,'f', decimals);
}

Coordinate& Coordinate::operator =(const geos::geom::Coordinate& crd){
    this->x = crd.x;
    this->y = crd.y;
    if (std::isnan(crd.z))
        this->z = rUNDEF;
    else
        this->z = crd.z;
    return *this;
}

Coordinate &Coordinate::operator =(const QVector3D &p2)
{
    this->x = p2.x();
    this->y = p2.y();
    this->z = p2.z();

    return *this;
}

//-----------------------------------------------
std::vector<double> Ilwis::operator-(const Ilwis::Coordinate& p1, const Ilwis::Coordinate& p2) {
    if (!(p1.isValid() && p2.isValid()))
        return std::vector<double>();
    std::vector<double> v(3,0);
    v[0] = p1.x - p2.x;
    v[1] = p1.y - p2.y ;
    if ( p1.z != p1.undefined() && p2.z != p2.undefined())
        v[2] = p1.z - p2.z ;
    return v;
}

Ilwis::Coordinate Ilwis::operator+(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x + vec[0];
    p3.y = p1.y + vec[1] ;
    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z + vec[2];

    return p3;
}

Ilwis::Coordinate Ilwis::operator-(const Ilwis::Coordinate& p1, const std::vector<double>& vec) {
    if (p1.isValid() == false ||  vec.size() < 2 )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x - vec[0];
    p3.y = p1.y - vec[1] ;

    if ( vec.size() >= 3 && p1.z != p1.undefined())
        p3.z = p1.z - vec[2];
    return p3;
}

Ilwis::Coordinate Ilwis::operator*(const Ilwis::Coordinate& p1, double v) {
    if (p1.isValid() == false || v == rUNDEF )
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x * v;
    p3.y = p1.y * v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z * v;
    return p3;
}

Ilwis::Coordinate Ilwis::operator/(const Ilwis::Coordinate& p1, double v) {
    if (!p1.isValid() || v == 0)
        return Ilwis::Coordinate();
    Ilwis::Coordinate p3 = p1;
    p3.x =p1.x / v;
    p3.y = p1.y / v ;
    if ( p1.z != p1.undefined())
        p3.z = p3.z / v;
    return p3;
}

//---------------------------------------------------------------------------
LatLon::LatLon(){

}

LatLon::LatLon(const Angle &latd, const Angle &lond, double h){
    lat(latd);
    lon(lond);
    z= h;
}

LatLon::LatLon(const QString &lat, const QString &lon)
{
    auto func = [] ( QString value) -> double {
        bool ok;
        double v =  value.toDouble(&ok);
        if ( ok) // we were already a decimal variant; no further parsing needed
            return v;
        value = value.trimmed();
        double sign = 1.0;
        if ( value.right(1) == "S"){
            sign = -1.0;
        }else if ( value.right(1) == "W") {
            sign = -1.0;
        }
        value.right(1).toLong(&ok);
        if ( !ok)
            value = value.left(value.size() -2);
        QStringList parts = value.split(" ");
        v  = parts[0].toDouble(&ok);
        if ( ok && parts.size() > 1) {
            v += parts[1].toDouble(&ok) / 60.0;
            if ( ok && parts.size() == 3){
                v += parts[2].toDouble(&ok)/ 3600.0;
            }
        }
        if ( ok)
            return sign * v;
        return rUNDEF;
    };
    y = func( lat);
    x = func( lon);
    if ( x == rUNDEF || y == rUNDEF)
        x = y = rUNDEF;
}

Angle LatLon::lat() const{
    return y;
}
Angle LatLon::lon() const{
    return x;
}

void LatLon::lat(const Angle& val){
    y = val.degrees();
}

void LatLon::lon(const Angle& val){
    x = val.degrees();
}

QString LatLon::toString(int decimals, bool ) const
{
    if ( !isValid())
        return "";

    auto ll = [&](double loc) -> QString {
        const QChar chardgr(0260);
        int dgr = std::abs((int)loc);
        int dmin = (std::abs(loc) - dgr) * 60;
        double dsec = (std::abs(loc) -  dgr - dmin/60.0) * 60.0;
        dgr = loc < 0 ? -dgr : dgr;

        QString result = QString("%1%2 %3\' %4\'\'").arg(dgr).arg(chardgr).arg(dmin).arg(dsec,0,'f', decimals);
        return result;
    };
    QString llstring = QString("%1 %2").arg(ll(y)).arg(ll(x));

    return llstring;
}
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

#ifndef CORE__MISC_HPP
#define CORE__MISC_HPP

#include <list>

template <class T>
T* getNext(std::list<T*> &list, T* node) {
  auto it = list.begin();
  while (it != list.end()) {
    if (*it == node) {
      ++it;
      return *it;
    }
    ++it;
  }
  return nullptr;
}

void die(const char *message, ...);

#define UNUSED(x) ((void)x)

#endif
<commit_msg>core/misc.hpp: Fixed getNext(..)<commit_after>// See LICENSE file for copyright and license details.

#ifndef CORE__MISC_HPP
#define CORE__MISC_HPP

#include <cassert>
#include <list>

// TODO: Rewrite :(
template <class T>
T* getNext(std::list<T*> &list, T* node) {
  assert(node);
  auto it = list.begin();
  while (it != list.end()) {
    if (*it == node) {
      ++it;
      if (it == list.end()) {
        return nullptr;
      }
      return *it;
    }
    ++it;
  }
  return nullptr;
}

void die(const char *message, ...);

#define UNUSED(x) ((void)x)

#endif
<|endoftext|>


<commit_before>/**
 * @file Cosa/Alarm.hh
 * @version 1.0
 *
 * @section License
 * Copyright (C) 2014, Mikael Patel
 *
 * 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.
 *
 * This file is part of the Arduino Che Cosa project.
 */

#ifndef COSA_ALARM_HH
#define COSA_ALARM_HH

#include "Cosa/Types.h"
#include "Cosa/Time.hh"
#include "Cosa/Linkage.hh"
#include "Cosa/Periodic.hh"

/**
 * Cosa Alarm handler; Allows one-time or periodic activities to be
 * schedule with a seconds level resolution. Requires Watchdog with
 * timeout events and RTC for more accurate time-keeping.
 */
class Alarm : private Link {
public:
  /**
   * Construct alarm with given timeout period in seconds.
   * The alarm must be enabled to become active.
   * @param[in] period seconds.
   */
  Alarm(uint32_t period = 0L) :
    Link(),
    m_when(0L),
    m_period(period)
  {
  }

  /**
   * Returns current time in seconds. The current time is from startup
   * or latest set_time().
   * @return seconds.
   */
  static clock_t time()
  {
    return (s_ticks);
  }

  /**
   * Set the alarm manager clock with given time in seconds. The
   * Cosa/Time time_t data type may be used to map to calender date
   * and time.
   * @param[in] now current time in seconds.
   */
  static void set_time(clock_t now)
  {
    s_ticks = now;
  }

  /**
   * Increment alarm manager ticks (seconds) counter and execute
   * all alarm handlers that have expired. This function must be
   * called by a RTC callback. The default scheduler is based on the
   * Watchdog and Periodic timeout events.
   */
  static void tick();

  /**
   * Set alarm handler next timeout to the given number of seconds
   * from current time (delta). If the parameter is zero the alarm
   * handler periodic value is used as increment.
   * @param[in] seconds to alarm.
   */
  void next_alarm(uint32_t seconds = 0L)
    __attribute__((always_inline))
  {
    if (seconds == 0L) seconds = m_period;
    m_when = s_ticks + seconds;
  }

  /**
   * Set alarm handler timeout to the given number of seconds from
   * current time (delta). If the parameter is zero the alarm handler
   * The alarm must be enabled to become active.
   * periodic value is used as delta.
   * @param[in] seconds to alarm.
   */
  void set_alarm(clock_t time)
  {
    m_when = time;
  }

  /**
   * Return alarm handler periodic timeout.
   * @return seconds.
   */
  uint16_t period() const
  {
    return (m_period);
  }

  /**
   * Set alarm handler periodic timeout to the given number of
   * seconds. The alarm will be automatically rescheduled (enabled)
   * with the given period.
   * @param[in] seconds periodic timeout.
   */
  void set_period(uint32_t seconds)
  {
    m_period = seconds;
  }

  /**
   * Get the time remaining before the alarm expires.
   * @return seconds.
   */
  uint32_t expires_in() const
  {
    if (m_when > s_ticks)
      return (m_when - s_ticks);
    else
      return (0);
  }

  /**
   * Schedule the alarm handler.
   */
  void enable();

  /**
   * Remove the alarm handler from the schedule.
   */
  void disable()
    __attribute__((always_inline))
  {
    detach();
  }

  /**
   * @override Alarm
   * Alarm action member function. Called when the alarm expires.
   * If the periodic timeout is non-zero the alarm is enabled again
   * otherwise a new timeout must be set and the alarm enabled.
   */
  virtual void run() = 0;

  /**
   * Watchdog based periodic(128 ms) scheduler. The setup function
   * must initiate the Watchdog to generate timeout event,
   * @code
   *   Watchdog::begin(ms, mode, Watchdog::push_timeout_events)
   * @endcode
   * and the loop function must contain an event dispatcher,
   * @code
   *   Event event;
   *   Event::queue.await(&event);
   *   event.dispatch();
   * @endcode
   * The alarm manager will check for expired alarms and call the
   * respective alarm handlers. The RTC is used for more accurate
   * timekeeping.
   */
  class Scheduler : public Periodic {
  public:
    Scheduler() :
      Periodic(128),
      m_seconds(0L)
    {}
    virtual void run();
  private:
    uint32_t m_seconds;
  };

private:
  static clock_t s_ticks;	//!< Current time in seconds.
  static Head s_queue;		//!< Alarm handler queue.
  uint32_t m_when;		//!< Alarm timeout in seconds.
  uint32_t m_period;		//!< Period in seconds.
};
#endif

<commit_msg>Return 0 when alarm is disabled.<commit_after>/**
 * @file Cosa/Alarm.hh
 * @version 1.0
 *
 * @section License
 * Copyright (C) 2014, Mikael Patel
 *
 * 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.
 *
 * This file is part of the Arduino Che Cosa project.
 */

#ifndef COSA_ALARM_HH
#define COSA_ALARM_HH

#include "Cosa/Types.h"
#include "Cosa/Time.hh"
#include "Cosa/Linkage.hh"
#include "Cosa/Periodic.hh"

/**
 * Cosa Alarm handler; Allows one-time or periodic activities to be
 * schedule with a seconds level resolution. Requires Watchdog with
 * timeout events and RTC for more accurate time-keeping.
 */
class Alarm : private Link {
public:
  /**
   * Construct alarm with given timeout period in seconds.
   * The alarm must be enabled to become active.
   * @param[in] period seconds.
   */
  Alarm(uint32_t period = 0L) :
    Link(),
    m_when(0L),
    m_period(period)
  {
  }

  /**
   * Returns current time in seconds. The current time is from startup
   * or latest set_time().
   * @return seconds.
   */
  static clock_t time()
  {
    return (s_ticks);
  }

  /**
   * Set the alarm manager clock with given time in seconds. The
   * Cosa/Time time_t data type may be used to map to calender date
   * and time.
   * @param[in] now current time in seconds.
   */
  static void set_time(clock_t now)
  {
    s_ticks = now;
  }

  /**
   * Increment alarm manager ticks (seconds) counter and execute
   * all alarm handlers that have expired. This function must be
   * called by a RTC callback. The default scheduler is based on the
   * Watchdog and Periodic timeout events.
   */
  static void tick();

  /**
   * Set alarm handler next timeout to the given number of seconds
   * from current time (delta). If the parameter is zero the alarm
   * handler periodic value is used as increment.
   * @param[in] seconds to alarm.
   */
  void next_alarm(uint32_t seconds = 0L)
    __attribute__((always_inline))
  {
    if (seconds == 0L) seconds = m_period;
    m_when = s_ticks + seconds;
  }

  /**
   * Set alarm handler timeout to the given number of seconds from
   * current time (delta). If the parameter is zero the alarm handler
   * The alarm must be enabled to become active.
   * periodic value is used as delta.
   * @param[in] seconds to alarm.
   */
  void set_alarm(clock_t time)
  {
    m_when = time;
  }

  /**
   * Return alarm handler periodic timeout.
   * @return seconds.
   */
  uint16_t period() const
  {
    return (m_period);
  }

  /**
   * Set alarm handler periodic timeout to the given number of
   * seconds. The alarm will be automatically rescheduled (enabled)
   * with the given period.
   * @param[in] seconds periodic timeout.
   */
  void set_period(uint32_t seconds)
  {
    m_period = seconds;
  }

  /**
   * Get the time remaining before the alarm expires.
   * @return seconds.
   */
  uint32_t expires_in() const
    __attribute__((always_inline))
  {
    if (m_when > s_ticks)
      return (m_when - s_ticks);
    else
      return (0);
  }

  /**
   * Schedule the alarm handler.
   */
  void enable();

  /**
   * Remove the alarm handler from the schedule.
   */
  void disable()
    __attribute__((always_inline))
  {
    detach();
    m_when = 0L;
  }

  /**
   * @override Alarm
   * Alarm action member function. Called when the alarm expires.
   * If the periodic timeout is non-zero the alarm is enabled again
   * otherwise a new timeout must be set and the alarm enabled.
   */
  virtual void run() = 0;

  /**
   * Watchdog based periodic(128 ms) scheduler. The setup function
   * must initiate the Watchdog to generate timeout event,
   * @code
   *   Watchdog::begin(ms, mode, Watchdog::push_timeout_events)
   * @endcode
   * and the loop function must contain an event dispatcher,
   * @code
   *   Event event;
   *   Event::queue.await(&event);
   *   event.dispatch();
   * @endcode
   * The alarm manager will check for expired alarms and call the
   * respective alarm handlers. The RTC is used for more accurate
   * timekeeping.
   */
  class Scheduler : public Periodic {
  public:
    Scheduler() :
      Periodic(128),
      m_seconds(0L)
    {}
    virtual void run();
  private:
    uint32_t m_seconds;
  };

private:
  static clock_t s_ticks;	//!< Current time in seconds.
  static Head s_queue;		//!< Alarm handler queue.
  uint32_t m_when;		//!< Alarm timeout in seconds.
  uint32_t m_period;		//!< Period in seconds.
};
#endif

<|endoftext|>


<commit_before>/******************************************************************************\
* LuaFunction.cpp                                                              *
* A C++ equivalent of a Lua function.                                          *
*                                                                              *
*                                                                              *
* Copyright (C) 2005-2010 by Leandro Motta Barros.                             *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to     *
* deal in the Software without restriction, including without limitation the   *
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  *
* sell copies of the Software, and to permit persons to whom the Software is   *
* furnished to do so, subject to the following conditions:                     *
*                                                                              *
* The above copyright notice and this permission notice shall be included in   *
* all copies or substantial portions of the Software.                          *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
* IN THE SOFTWARE.                                                             *
\******************************************************************************/

#include <Diluculum/LuaFunction.hpp>
#include <cstring>

namespace Diluculum
{
   // - LuaFunction::LuaFunction -----------------------------------------------
   LuaFunction::LuaFunction (const::std::string& luaChunk)
      : functionType_(LUA_LUA_FUNCTION), size_(luaChunk.size()),
        data_(new char[size_])
   {
      memcpy(data_.get(), luaChunk.c_str(), size_);
   }

   LuaFunction::LuaFunction (const void* data, size_t size)
      : functionType_(LUA_LUA_FUNCTION), size_(size), data_(new char[size_])
   {
      memcpy(data_.get(), data, size);
   }

   LuaFunction::LuaFunction (lua_CFunction func)
      : functionType_(LUA_C_FUNCTION), size_(sizeof(lua_CFunction)),
        data_(new char[sizeof(lua_CFunction)])
   {
      memcpy(data_.get(), reinterpret_cast<lua_CFunction*>(&func),
             sizeof(lua_CFunction));
   }

   LuaFunction::LuaFunction (const LuaFunction& other)
      : functionType_(other.functionType_),
        size_(other.getSize()), data_(new char[size_])
   {
      memcpy (data_.get(), other.getData(), getSize());
   }

   // - LuaFunction::getCFunction ----------------------------------------------
   lua_CFunction LuaFunction::getCFunction() const
   {
      assert(functionType_ == LUA_C_FUNCTION
             && "Called LuaFunction::getCFunction() for a non-C function.");

      return *reinterpret_cast<lua_CFunction*>(data_.get());
   }

   // - LuaFunction::setData ---------------------------------------------------
   void LuaFunction::setData (void* data, size_t size)
   {
      size_ = size;
      data_.reset (new char[size]);
      memcpy(data_.get(), data, size);
   }

   // - LuaFunction::operator= -------------------------------------------------
   const LuaFunction& LuaFunction::operator= (const LuaFunction& rhs)
   {
      size_ = rhs.getSize();
      functionType_ = rhs.functionType_;
      data_.reset (new char[getSize()]);
      memcpy (getData(), rhs.getData(), getSize());
      return *this;
   }

   // - LuaFunction::operator> -------------------------------------------------
   bool LuaFunction::operator> (const LuaFunction& rhs) const
   {
      if (functionType_ > rhs.functionType_)
         return true;
      else if (getSize() > rhs.getSize())
         return true;
      else if (getSize() < rhs.getSize())
         return false;
      else // getSize() == rhs.getSize()
         return memcmp (getData(), rhs.getData(), getSize()) > 0;
   }

   // - LuaFunction::operator< -------------------------------------------------
   bool LuaFunction::operator< (const LuaFunction& rhs) const
   {
      if (functionType_ < rhs.functionType_)
         return true;
      else if (getSize() < rhs.getSize())
         return true;
      else if (getSize() > rhs.getSize())
         return false;
      else // getSize() == rhs.getSize()
         return memcmp (getData(), rhs.getData(), getSize()) < 0;
   }

   // - LuaFunction::operator== ------------------------------------------------
   bool LuaFunction::operator== (const LuaFunction& rhs) const
   {
      return functionType_ == rhs.functionType_
         && getSize() == rhs.getSize()
         && memcmp (getData(), rhs.getData(), getSize()) == 0;
   }

   // - LuaFunction::operator!= ------------------------------------------------
   bool LuaFunction::operator!= (const LuaFunction& rhs) const
   {
      return functionType_ != rhs.functionType_
         || getSize() != rhs.getSize()
         || memcmp (getData(), rhs.getData(), getSize()) != 0;
   }

} // namespace Diluculum
<commit_msg>Replaced a 'const::std::string&' with a 'const std::string&'.<commit_after>/******************************************************************************\
* LuaFunction.cpp                                                              *
* A C++ equivalent of a Lua function.                                          *
*                                                                              *
*                                                                              *
* Copyright (C) 2005-2010 by Leandro Motta Barros.                             *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to     *
* deal in the Software without restriction, including without limitation the   *
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or  *
* sell copies of the Software, and to permit persons to whom the Software is   *
* furnished to do so, subject to the following conditions:                     *
*                                                                              *
* The above copyright notice and this permission notice shall be included in   *
* all copies or substantial portions of the Software.                          *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR   *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,     *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER       *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS *
* IN THE SOFTWARE.                                                             *
\******************************************************************************/

#include <Diluculum/LuaFunction.hpp>
#include <cstring>

namespace Diluculum
{
   // - LuaFunction::LuaFunction -----------------------------------------------
   LuaFunction::LuaFunction (const std::string& luaChunk)
      : functionType_(LUA_LUA_FUNCTION), size_(luaChunk.size()),
        data_(new char[size_])
   {
      memcpy(data_.get(), luaChunk.c_str(), size_);
   }

   LuaFunction::LuaFunction (const void* data, size_t size)
      : functionType_(LUA_LUA_FUNCTION), size_(size), data_(new char[size_])
   {
      memcpy(data_.get(), data, size);
   }

   LuaFunction::LuaFunction (lua_CFunction func)
      : functionType_(LUA_C_FUNCTION), size_(sizeof(lua_CFunction)),
        data_(new char[sizeof(lua_CFunction)])
   {
      memcpy(data_.get(), reinterpret_cast<lua_CFunction*>(&func),
             sizeof(lua_CFunction));
   }

   LuaFunction::LuaFunction (const LuaFunction& other)
      : functionType_(other.functionType_),
        size_(other.getSize()), data_(new char[size_])
   {
      memcpy (data_.get(), other.getData(), getSize());
   }

   // - LuaFunction::getCFunction ----------------------------------------------
   lua_CFunction LuaFunction::getCFunction() const
   {
      assert(functionType_ == LUA_C_FUNCTION
             && "Called LuaFunction::getCFunction() for a non-C function.");

      return *reinterpret_cast<lua_CFunction*>(data_.get());
   }

   // - LuaFunction::setData ---------------------------------------------------
   void LuaFunction::setData (void* data, size_t size)
   {
      size_ = size;
      data_.reset (new char[size]);
      memcpy(data_.get(), data, size);
   }

   // - LuaFunction::operator= -------------------------------------------------
   const LuaFunction& LuaFunction::operator= (const LuaFunction& rhs)
   {
      size_ = rhs.getSize();
      functionType_ = rhs.functionType_;
      data_.reset (new char[getSize()]);
      memcpy (getData(), rhs.getData(), getSize());
      return *this;
   }

   // - LuaFunction::operator> -------------------------------------------------
   bool LuaFunction::operator> (const LuaFunction& rhs) const
   {
      if (functionType_ > rhs.functionType_)
         return true;
      else if (getSize() > rhs.getSize())
         return true;
      else if (getSize() < rhs.getSize())
         return false;
      else // getSize() == rhs.getSize()
         return memcmp (getData(), rhs.getData(), getSize()) > 0;
   }

   // - LuaFunction::operator< -------------------------------------------------
   bool LuaFunction::operator< (const LuaFunction& rhs) const
   {
      if (functionType_ < rhs.functionType_)
         return true;
      else if (getSize() < rhs.getSize())
         return true;
      else if (getSize() > rhs.getSize())
         return false;
      else // getSize() == rhs.getSize()
         return memcmp (getData(), rhs.getData(), getSize()) < 0;
   }

   // - LuaFunction::operator== ------------------------------------------------
   bool LuaFunction::operator== (const LuaFunction& rhs) const
   {
      return functionType_ == rhs.functionType_
         && getSize() == rhs.getSize()
         && memcmp (getData(), rhs.getData(), getSize()) == 0;
   }

   // - LuaFunction::operator!= ------------------------------------------------
   bool LuaFunction::operator!= (const LuaFunction& rhs) const
   {
      return functionType_ != rhs.functionType_
         || getSize() != rhs.getSize()
         || memcmp (getData(), rhs.getData(), getSize()) != 0;
   }

} // namespace Diluculum
<|endoftext|>