<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "random.h"

#ifdef WIN32
#include "compat.h" // for Windows API
#endif
#include "serialize.h"        // for begin_ptr(vec)
#include "util.h"             // for LogPrint()
#include "utiltime.h"         // for GetTime()

#include <limits>

#ifndef WIN32
#include <sys/time.h>
#endif

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>

static inline int64_t GetPerformanceCounter()
{
    int64_t nCounter = 0;
#ifdef WIN32
    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
#else
    timeval t;
    gettimeofday(&t, NULL);
    nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
#endif
    return nCounter;
}

void RandAddSeed()
{
    // Seed with CPU performance counter
    int64_t nCounter = GetPerformanceCounter();
    RAND_add(&nCounter, sizeof(nCounter), 1.5);
    OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter));
}

void RandAddSeedPerfmon()
{
    RandAddSeed();

    // This can take up to 2 seconds, so only do it every 10 minutes
    static int64_t nLastPerfmon;
    if (GetTime() < nLastPerfmon + 10 * 60)
        return;
    nLastPerfmon = GetTime();

#ifdef WIN32
    // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
    // Seed with the entire set of perfmon data
    std::vector<unsigned char> vData(250000, 0);
    long ret = 0;
    unsigned long nSize = 0;
    const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
    while (true) {
        nSize = vData.size();
        ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
        if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
            break;
        vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
    }
    RegCloseKey(HKEY_PERFORMANCE_DATA);
    if (ret == ERROR_SUCCESS) {
        RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
        OPENSSL_cleanse(begin_ptr(vData), nSize);
        LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
    } else {
        static bool warned = false; // Warn only once
        if (!warned) {
            printf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
            warned = true;
        }
    }
#endif
}

void GetRandBytes(unsigned char* buf, int num)
{
    if (RAND_bytes(buf, num) != 1) {
        printf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL));
        assert(false);
    }
}

uint64_t GetRand(uint64_t nMax)
{
    if (nMax == 0)
        return 0;

    // The range of the random source must be a multiple of the modulus
    // to give every possible output value an equal possibility
    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
    uint64_t nRand = 0;
    do {
        GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
    } while (nRand >= nRange);
    return (nRand % nMax);
}

int GetRandInt(int nMax)
{
    return GetRand(nMax);
}

uint256 GetRandHash()
{
    uint256 hash;
    GetRandBytes((unsigned char*)&hash, sizeof(hash));
    return hash;
}

uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
{
    // The seed values have some unlikely fixed points which we avoid.
    if (fDeterministic) {
        insecure_rand_Rz = insecure_rand_Rw = 11;
    } else {
        uint32_t tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x9068ffffU);
        insecure_rand_Rz = tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x464fffffU);
        insecure_rand_Rw = tmp;
    }
}
<commit_msg>Fix print function<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "random.h"

#ifdef WIN32
#include "compat.h" // for Windows API
#endif
#include "serialize.h"        // for begin_ptr(vec)
#include "util.h"             // for LogPrint()
#include "utiltime.h"         // for GetTime()

#include <limits>

#ifndef WIN32
#include <sys/time.h>
#endif

#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>

static inline int64_t GetPerformanceCounter()
{
    int64_t nCounter = 0;
#ifdef WIN32
    QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
#else
    timeval t;
    gettimeofday(&t, NULL);
    nCounter = (int64_t)(t.tv_sec * 1000000 + t.tv_usec);
#endif
    return nCounter;
}

void RandAddSeed()
{
    // Seed with CPU performance counter
    int64_t nCounter = GetPerformanceCounter();
    RAND_add(&nCounter, sizeof(nCounter), 1.5);
    OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter));
}

void RandAddSeedPerfmon()
{
    RandAddSeed();

    // This can take up to 2 seconds, so only do it every 10 minutes
    static int64_t nLastPerfmon;
    if (GetTime() < nLastPerfmon + 10 * 60)
        return;
    nLastPerfmon = GetTime();

#ifdef WIN32
    // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
    // Seed with the entire set of perfmon data
    std::vector<unsigned char> vData(250000, 0);
    long ret = 0;
    unsigned long nSize = 0;
    const size_t nMaxSize = 10000000; // Bail out at more than 10MB of performance data
    while (true) {
        nSize = vData.size();
        ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL, NULL, begin_ptr(vData), &nSize);
        if (ret != ERROR_MORE_DATA || vData.size() >= nMaxSize)
            break;
        vData.resize(std::max((vData.size() * 3) / 2, nMaxSize)); // Grow size of buffer exponentially
    }
    RegCloseKey(HKEY_PERFORMANCE_DATA);
    if (ret == ERROR_SUCCESS) {
        RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
        OPENSSL_cleanse(begin_ptr(vData), nSize);
        print("%s: %lu bytes\n", __func__, nSize);
    } else {
        static bool warned = false; // Warn only once
        if (!warned) {
            printf("%s: Warning: RegQueryValueExA(HKEY_PERFORMANCE_DATA) failed with code %i\n", __func__, ret);
            warned = true;
        }
    }
#endif
}

void GetRandBytes(unsigned char* buf, int num)
{
    if (RAND_bytes(buf, num) != 1) {
        printf("%s: OpenSSL RAND_bytes() failed with error: %s\n", __func__, ERR_error_string(ERR_get_error(), NULL));
        assert(false);
    }
}

uint64_t GetRand(uint64_t nMax)
{
    if (nMax == 0)
        return 0;

    // The range of the random source must be a multiple of the modulus
    // to give every possible output value an equal possibility
    uint64_t nRange = (std::numeric_limits<uint64_t>::max() / nMax) * nMax;
    uint64_t nRand = 0;
    do {
        GetRandBytes((unsigned char*)&nRand, sizeof(nRand));
    } while (nRand >= nRange);
    return (nRand % nMax);
}

int GetRandInt(int nMax)
{
    return GetRand(nMax);
}

uint256 GetRandHash()
{
    uint256 hash;
    GetRandBytes((unsigned char*)&hash, sizeof(hash));
    return hash;
}

uint32_t insecure_rand_Rz = 11;
uint32_t insecure_rand_Rw = 11;
void seed_insecure_rand(bool fDeterministic)
{
    // The seed values have some unlikely fixed points which we avoid.
    if (fDeterministic) {
        insecure_rand_Rz = insecure_rand_Rw = 11;
    } else {
        uint32_t tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x9068ffffU);
        insecure_rand_Rz = tmp;
        do {
            GetRandBytes((unsigned char*)&tmp, 4);
        } while (tmp == 0 || tmp == 0x464fffffU);
        insecure_rand_Rw = tmp;
    }
}
<|endoftext|>


<commit_before>/*
 * Pi 2 is connected to the ImP/IMU via UART, Camera via CSI, Burn Wire Relay
 * via GPIO and Pi 1 via Ethernet and GPIO for LO, SOE and SODS signals.
 *
 * This program controls most of the main logic and for the PIOneERs mission
 * on board REXUS.
 */

#include <stdio.h>
#include <cstdint>
#include <unistd.h> //For sleep
#include <stdlib.h>
#include <iostream>
#include <signal.h>

#include "pins.h"
#include "camera/camera.h"
#include "UART/UART.h"
#include "Ethernet/Ethernet.h"
#include "comms/pipes.h"
#include "comms/protocol.h"
#include "comms/packet.h"
#include "timing/timer.h"
#include "logger/logger.h"

#include <wiringPi.h>

Logger Log("/Docs/Logs/raspi2");

bool flight_mode = false;

// Global variable for the Camera and IMU
PiCamera Cam;

// Setup for the UART communications
int baud = 230400;
UART ImP;
comms::Pipe ImP_stream;

// Ethernet communication setup and variables (we are acting as client)
int port_no = 31415; // Random unused port for communication
comms::Pipe ethernet_stream;
Server ethernet_comms(port_no);

/**
 * Checks whether input is activated
 * @param pin: GPIO to be checked
 * @return true or false
 */
bool poll_input(int pin) {
	int count = 0;
	for (int i = 0; i < 5; i++) {
		count += digitalRead(pin);
		delayMicroseconds(200);
	}
	return (count < 3) ? true : false;
}

void signal_handler(int s) {
	Log("FATAL") << "Exiting program after signal " << s;
	if (Cam.is_running()) {
		Cam.stopVideo();
		Log("INFO") << "Stopping camera process";
	} else {
		Log("ERROR") << "Camera process died prematurely or did not start";
	}

	if (&ethernet_stream != NULL) {
		ethernet_stream.close_pipes();
		Log("INFO") << "Closed Ethernet communication";
	} else {
		Log("ERROR") << "Ethernet process died prematurely or did not start";
	}
	if (&ImP_stream != NULL) {
		ImP_stream.close_pipes();
		Log("INFO") << "Closed ImP communication";
	} else {
		Log("ERROR") << "ImP process died prematurely or did not start";
	}
	digitalWrite(BURNWIRE, 0);
	// TODO copy data to a further backup directory
	Log("INFO") << "Ending program, Pi rebooting";
	system("sudo reboot");
	exit(1); // This was an unexpected end so we will exit with an error!
}

int SODS_SIGNAL() {
	/*
	 * When the 'Start of Data Storage' signal is received all data recording
	 * is stopped (IMU and Camera) and power to the camera is cut off to stop
	 * shorting due to melting on re-entry. All data is copied into a backup
	 * directory.
	 */
	Log("INFO") << "SODS signal received";
	if (Cam.is_running()) {
		Cam.stopVideo();
		Log("INFO") << "Stopping camera process";
	} else {
		Log("ERROR") << "Camera process died prematurely or did not start";
	}

	if (&ethernet_stream != NULL) {
		ethernet_stream.close_pipes();
		Log("INFO") << "Closed Ethernet communication";
	} else {
		Log("ERROR") << "Ethernet process died prematurely or did not start";
	}
	if (&ImP_stream != NULL) {
		ImP_stream.close_pipes();
		Log("INFO") << "Closed ImP communication";
	} else {
		Log("ERROR") << "ImP process died prematurely or did not start";
	}
	digitalWrite(BURNWIRE, 0);
	digitalWrite(BURNWIRE, 0);
	// TODO copy data to a further backup directory
	Log("INFO") << "Ending program, Pi rebooting";
	system("sudo reboot");
	return 0;
}

int SOE_SIGNAL() {
	/*
	 * When the 'Start of Experiment' signal is received the boom needs to be
	 * deployed and the ImP and IMU to start taking measurements. For boom
	 * deployment is there is no increase in the encoder count or ?? seconds
	 * have passed since start of deployment then it is assumed that either the
	 * boom has reached it's full length or something has gone wrong and the
	 * count of the encoder is sent to ground.
	 */
	Log("INFO") << "SOE signal received";
	// Setup the ImP and start requesting data
	ImP_stream = ImP.startDataCollection("Docs/Data/Pi2/test");
	Log("INFO") << "Started data collection from ImP";
	comms::Packet p; // Buffer for reading data from the IMU stream
	// Trigger the burn wire for 10 seconds!
	Log("INFO") << "Triggering burnwire";
	digitalWrite(BURNWIRE, 1);
	Timer tmr;
	Log("INFO") << "Burn wire triggered" << std::endl;
	while (tmr.elapsed() < 10000) {
		// Get ImP data
		int n = ImP_stream.binread(&p, sizeof (p));
		if (n > 0) {
			Log("DATA (ImP)") << p;
			ethernet_stream.binwrite(&p, sizeof (p));
		}

		n = ethernet_stream.binread(&p, sizeof (p));
		if (n > 0)
			Log("DATA (PI1)") << p;
		Timer::sleep_ms(10);
	}
	digitalWrite(BURNWIRE, 0);
	Log("INFO") << "Burn wire off after " << tmr.elapsed() << " ms";
	Log("INFO") << "Waiting for SODS";
	// Wait for the next signal to continue the program
	bool signal_received = false;
	while (!signal_received) {
		signal_received = poll_input(SODS);
		// Read data from IMU_data_stream and echo it to Ethernet
		int n = ImP_stream.binread(&p, sizeof (p));
		if (n > 0) {
			Log("DATA (ImP)") << p;
			ethernet_stream.binwrite(&p, sizeof (p));
		}

		n = ethernet_stream.binread(&p, sizeof (p));
		if (n > 0)
			Log("DATA (PI1)") << p;
		Timer::sleep_ms(10);
	}
	return SODS_SIGNAL();
}

int LO_SIGNAL() {
	/*
	 * When the 'Lift Off' signal is received from the REXUS Module the cameras
	 * are set to start recording video and we then wait to receive the 'Start
	 * of Experiment' signal (when the nose-cone is ejected)
	 */
	Log("INFO") << "LO signal received";
	Cam.startVideo("Docs/Video/rexus_video");
	Log("INFO") << "Camera started recording video";
	// Poll the SOE pin until signal is received
	Log("INFO") << "Waiting for SOE";
	bool signal_received = false;
	while (!signal_received) {
		Timer::sleep_ms(10);
		signal_received = poll_input(SOE);
		// TODO Implement communications with RXSM
	}
	return SOE_SIGNAL();
}

int main() {
	/*
	 * This part of the program is run before the Lift-Off. In effect it
	 * continually listens for commands from the ground station and runs any
	 * required tests, regularly reporting status until the LO Signal is
	 * received.
	 */
	signal(SIGINT, signal_handler);
	// Create necessary directories for saving files
	system("mkdir -p Docs/Data/Pi1 Docs/Data/Pi2 Docs/Data/test Docs/Video Docs/Logs");
	Log.start_log();
	Log("INFO") << "Pi2 is alive";
	wiringPiSetup();
	// Setup main signal pins
	pinMode(LO, INPUT);
	pullUpDnControl(LO, PUD_UP);
	pinMode(SOE, INPUT);
	pullUpDnControl(SOE, PUD_UP);
	pinMode(SODS, INPUT);
	pullUpDnControl(SODS, PUD_UP);
	pinMode(ALIVE, OUTPUT);
	Log("INFO") << "Main signal pins setup";
	// Setup pins and check whether we are in flight mode
	pinMode(LAUNCH_MODE, INPUT);
	pullUpDnControl(LAUNCH_MODE, PUD_UP);
	flight_mode = digitalRead(LAUNCH_MODE);
	Log("INFO") << (flight_mode ? "flight mode enabled" : "test mode enabled");

	// Setup Burn Wire
	pinMode(BURNWIRE, OUTPUT);

	// Setup server and wait for client
	digitalWrite(ALIVE, 1);
	Log("INFO") << "Waiting for connection from client on port " << port_no;
	try {
		ethernet_stream = ethernet_comms.run("Docs/Data/Pi1/backup.txt");
	} catch (EthernetException e) {
		Log("FATAL") << "Unable to connect to pi 1";
		signal_handler(-5);
	}
	Log("INFO") << "Connection to Pi1 successfil";
	Log("INFO") << "Waiting for LO signal";
	// Check for LO signal.
	std::string msg;
	bool signal_received = false;
	comms::Packet p;
	comms::byte1_t id;
	comms::byte2_t index;
	char data[16];
	while (!signal_received) {
		Timer::sleep_ms(10);
		signal_received = poll_input(LO);
		// TODO Implement communications with Pi 1
		int n = ethernet_stream.binread(&p, sizeof (p));
		if (n > 0) {
			Log("DATA (PI1)") << p;
			comms::Protocol::unpack(p, id, index, data);
			Log("DATA (PI1)") << "Unpacked\n\t\"" << std::string(data) << "\"";
			//TODO handle incoming commands!
		}
	}
	LO_SIGNAL();
	system("sudo reboot");
	return 0;
}
<commit_msg>Debugging raspi2.cpp<commit_after>/*
 * Pi 2 is connected to the ImP/IMU via UART, Camera via CSI, Burn Wire Relay
 * via GPIO and Pi 1 via Ethernet and GPIO for LO, SOE and SODS signals.
 *
 * This program controls most of the main logic and for the PIOneERs mission
 * on board REXUS.
 */

#include <stdio.h>
#include <cstdint>
#include <unistd.h> //For sleep
#include <stdlib.h>
#include <iostream>
#include <signal.h>

#include "pins.h"
#include "camera/camera.h"
#include "UART/UART.h"
#include "Ethernet/Ethernet.h"
#include "comms/pipes.h"
#include "comms/protocol.h"
#include "comms/packet.h"
#include "timing/timer.h"
#include "logger/logger.h"

#include <wiringPi.h>

Logger Log("/Docs/Logs/raspi2");

bool flight_mode = false;

// Global variable for the Camera and IMU
PiCamera Cam;

// Setup for the UART communications
int baud = 230400;
ImP IMP(baud);
comms::Pipe ImP_stream;

// Ethernet communication setup and variables (we are acting as client)
int port_no = 31415; // Random unused port for communication
comms::Pipe ethernet_stream;
Server ethernet_comms(port_no);

/**
 * Checks whether input is activated
 * @param pin: GPIO to be checked
 * @return true or false
 */
bool poll_input(int pin) {
	int count = 0;
	for (int i = 0; i < 5; i++) {
		count += digitalRead(pin);
		delayMicroseconds(200);
	}
	return (count < 3) ? true : false;
}

void signal_handler(int s) {
	Log("FATAL") << "Exiting program after signal " << s;
	if (Cam.is_running()) {
		Cam.stopVideo();
		Log("INFO") << "Stopping camera process";
	} else {
		Log("ERROR") << "Camera process died prematurely or did not start";
	}

	if (&ethernet_stream != NULL) {
		ethernet_stream.close_pipes();
		Log("INFO") << "Closed Ethernet communication";
	} else {
		Log("ERROR") << "Ethernet process died prematurely or did not start";
	}
	if (&ImP_stream != NULL) {
		ImP_stream.close_pipes();
		Log("INFO") << "Closed ImP communication";
	} else {
		Log("ERROR") << "ImP process died prematurely or did not start";
	}
	digitalWrite(BURNWIRE, 0);
	// TODO copy data to a further backup directory
	Log("INFO") << "Ending program, Pi rebooting";
	system("sudo reboot");
	exit(1); // This was an unexpected end so we will exit with an error!
}

int SODS_SIGNAL() {
	/*
	 * When the 'Start of Data Storage' signal is received all data recording
	 * is stopped (IMU and Camera) and power to the camera is cut off to stop
	 * shorting due to melting on re-entry. All data is copied into a backup
	 * directory.
	 */
	Log("INFO") << "SODS signal received";
	if (Cam.is_running()) {
		Cam.stopVideo();
		Log("INFO") << "Stopping camera process";
	} else {
		Log("ERROR") << "Camera process died prematurely or did not start";
	}

	if (&ethernet_stream != NULL) {
		ethernet_stream.close_pipes();
		Log("INFO") << "Closed Ethernet communication";
	} else {
		Log("ERROR") << "Ethernet process died prematurely or did not start";
	}
	if (&ImP_stream != NULL) {
		ImP_stream.close_pipes();
		Log("INFO") << "Closed ImP communication";
	} else {
		Log("ERROR") << "ImP process died prematurely or did not start";
	}
	digitalWrite(BURNWIRE, 0);
	digitalWrite(BURNWIRE, 0);
	// TODO copy data to a further backup directory
	Log("INFO") << "Ending program, Pi rebooting";
	system("sudo reboot");
	return 0;
}

int SOE_SIGNAL() {
	/*
	 * When the 'Start of Experiment' signal is received the boom needs to be
	 * deployed and the ImP and IMU to start taking measurements. For boom
	 * deployment is there is no increase in the encoder count or ?? seconds
	 * have passed since start of deployment then it is assumed that either the
	 * boom has reached it's full length or something has gone wrong and the
	 * count of the encoder is sent to ground.
	 */
	Log("INFO") << "SOE signal received";
	// Setup the ImP and start requesting data
	ImP_stream = IMP.startDataCollection("Docs/Data/Pi2/test");
	Log("INFO") << "Started data collection from ImP";
	comms::Packet p; // Buffer for reading data from the IMU stream
	// Trigger the burn wire for 10 seconds!
	Log("INFO") << "Triggering burnwire";
	digitalWrite(BURNWIRE, 1);
	Timer tmr;
	Log("INFO") << "Burn wire triggered" << std::endl;
	while (tmr.elapsed() < 10000) {
		// Get ImP data
		int n = ImP_stream.binread(&p, sizeof (p));
		if (n > 0) {
			Log("DATA (ImP)") << p;
			ethernet_stream.binwrite(&p, sizeof (p));
		}

		n = ethernet_stream.binread(&p, sizeof (p));
		if (n > 0)
			Log("DATA (PI1)") << p;
		Timer::sleep_ms(10);
	}
	digitalWrite(BURNWIRE, 0);
	Log("INFO") << "Burn wire off after " << tmr.elapsed() << " ms";
	Log("INFO") << "Waiting for SODS";
	// Wait for the next signal to continue the program
	bool signal_received = false;
	while (!signal_received) {
		signal_received = poll_input(SODS);
		// Read data from IMU_data_stream and echo it to Ethernet
		int n = ImP_stream.binread(&p, sizeof (p));
		if (n > 0) {
			Log("DATA (ImP)") << p;
			ethernet_stream.binwrite(&p, sizeof (p));
		}

		n = ethernet_stream.binread(&p, sizeof (p));
		if (n > 0)
			Log("DATA (PI1)") << p;
		Timer::sleep_ms(10);
	}
	return SODS_SIGNAL();
}

int LO_SIGNAL() {
	/*
	 * When the 'Lift Off' signal is received from the REXUS Module the cameras
	 * are set to start recording video and we then wait to receive the 'Start
	 * of Experiment' signal (when the nose-cone is ejected)
	 */
	Log("INFO") << "LO signal received";
	Cam.startVideo("Docs/Video/rexus_video");
	Log("INFO") << "Camera started recording video";
	// Poll the SOE pin until signal is received
	Log("INFO") << "Waiting for SOE";
	bool signal_received = false;
	while (!signal_received) {
		Timer::sleep_ms(10);
		signal_received = poll_input(SOE);
		// TODO Implement communications with RXSM
	}
	return SOE_SIGNAL();
}

int main() {
	/*
	 * This part of the program is run before the Lift-Off. In effect it
	 * continually listens for commands from the ground station and runs any
	 * required tests, regularly reporting status until the LO Signal is
	 * received.
	 */
	signal(SIGINT, signal_handler);
	// Create necessary directories for saving files
	system("mkdir -p Docs/Data/Pi1 Docs/Data/Pi2 Docs/Data/test Docs/Video Docs/Logs");
	Log.start_log();
	Log("INFO") << "Pi2 is alive";
	wiringPiSetup();
	// Setup main signal pins
	pinMode(LO, INPUT);
	pullUpDnControl(LO, PUD_UP);
	pinMode(SOE, INPUT);
	pullUpDnControl(SOE, PUD_UP);
	pinMode(SODS, INPUT);
	pullUpDnControl(SODS, PUD_UP);
	pinMode(ALIVE, OUTPUT);
	Log("INFO") << "Main signal pins setup";
	// Setup pins and check whether we are in flight mode
	pinMode(LAUNCH_MODE, INPUT);
	pullUpDnControl(LAUNCH_MODE, PUD_UP);
	flight_mode = digitalRead(LAUNCH_MODE);
	Log("INFO") << (flight_mode ? "flight mode enabled" : "test mode enabled");

	// Setup Burn Wire
	pinMode(BURNWIRE, OUTPUT);

	// Setup server and wait for client
	digitalWrite(ALIVE, 1);
	Log("INFO") << "Waiting for connection from client on port " << port_no;
	try {
		ethernet_stream = ethernet_comms.run("Docs/Data/Pi1/backup.txt");
	} catch (EthernetException e) {
		Log("FATAL") << "Unable to connect to pi 1";
		signal_handler(-5);
	}
	Log("INFO") << "Connection to Pi1 successfil";
	Log("INFO") << "Waiting for LO signal";
	// Check for LO signal.
	std::string msg;
	bool signal_received = false;
	comms::Packet p;
	comms::byte1_t id;
	comms::byte2_t index;
	char data[16];
	while (!signal_received) {
		Timer::sleep_ms(10);
		signal_received = poll_input(LO);
		// TODO Implement communications with Pi 1
		int n = ethernet_stream.binread(&p, sizeof (p));
		if (n > 0) {
			Log("DATA (PI1)") << p;
			comms::Protocol::unpack(p, id, index, data);
			Log("DATA (PI1)") << "Unpacked\n\t\"" << std::string(data) << "\"";
			//TODO handle incoming commands!
		}
	}
	LO_SIGNAL();
	system("sudo reboot");
	return 0;
}
<|endoftext|>


<commit_before>//==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a helper to run the internalization part of LTO.
//
//===----------------------------------------------------------------------===//

#include "LTOInternalize.h"

#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Transforms/IPO/Internalize.h"

using namespace llvm;

namespace {
// Helper class that populate the array of symbols used in inlined assembly.
class ComputeAsmUsed {
public:
  ComputeAsmUsed(const StringSet<> &AsmUndefinedRefs, const TargetMachine &TM,
                 const Module &TheModule,
                 SmallPtrSetImpl<const GlobalValue *> &AsmUsed)
      : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), AsmUsed(AsmUsed) {
    accumulateAndSortLibcalls(TheModule);
    for (const Function &F : TheModule)
      findAsmUses(F);
    for (const GlobalVariable &GV : TheModule.globals())
      findAsmUses(GV);
    for (const GlobalAlias &GA : TheModule.aliases())
      findAsmUses(GA);
  }

private:
  // Inputs
  const StringSet<> &AsmUndefinedRefs;
  const TargetMachine &TM;

  // Temps
  llvm::Mangler Mangler;
  std::vector<StringRef> Libcalls;

  // Output
  SmallPtrSetImpl<const GlobalValue *> &AsmUsed;

  // Collect names of runtime library functions. User-defined functions with the
  // same names are added to llvm.compiler.used to prevent them from being
  // deleted by optimizations.
  void accumulateAndSortLibcalls(const Module &TheModule) {
    TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));
    TargetLibraryInfo TLI(TLII);

    // TargetLibraryInfo has info on C runtime library calls on the current
    // target.
    for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
         I != E; ++I) {
      LibFunc::Func F = static_cast<LibFunc::Func>(I);
      if (TLI.has(F))
        Libcalls.push_back(TLI.getName(F));
    }

    SmallPtrSet<const TargetLowering *, 1> TLSet;

    for (const Function &F : TheModule) {
      const TargetLowering *Lowering =
          TM.getSubtargetImpl(F)->getTargetLowering();

      if (Lowering && TLSet.insert(Lowering).second)
        // TargetLowering has info on library calls that CodeGen expects to be
        // available, both from the C runtime and compiler-rt.
        for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
             I != E; ++I)
          if (const char *Name =
                  Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
            Libcalls.push_back(Name);
    }

    array_pod_sort(Libcalls.begin(), Libcalls.end());
    Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
                   Libcalls.end());
  }

  void findAsmUses(const GlobalValue &GV) {
    // There are no restrictions to apply to declarations.
    if (GV.isDeclaration())
      return;

    // There is nothing more restrictive than private linkage.
    if (GV.hasPrivateLinkage())
      return;

    SmallString<64> Buffer;
    TM.getNameWithPrefix(Buffer, &GV, Mangler);

    if (AsmUndefinedRefs.count(Buffer))
      AsmUsed.insert(&GV);

    // Conservatively append user-supplied runtime library functions to
    // llvm.compiler.used.  These could be internalized and deleted by
    // optimizations like -globalopt, causing problems when later optimizations
    // add new library calls (e.g., llvm.memset => memset and printf => puts).
    // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
    if (isa<Function>(GV) &&
        std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
      AsmUsed.insert(&GV);
  }
};

} // namespace anonymous

static void findUsedValues(GlobalVariable *LLVMUsed,
                           SmallPtrSetImpl<const GlobalValue *> &UsedValues) {
  if (!LLVMUsed)
    return;

  ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
    if (GlobalValue *GV =
            dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
      UsedValues.insert(GV);
}

// mark which symbols can not be internalized
void llvm::LTOInternalize(
    Module &TheModule, const TargetMachine &TM,
    const std::function<bool(const GlobalValue &)> &MustPreserveSymbols,
    const StringSet<> &AsmUndefinedRefs) {
  SmallPtrSet<const GlobalValue *, 8> AsmUsed;
  ComputeAsmUsed(AsmUndefinedRefs, TM, TheModule, AsmUsed);

  GlobalVariable *LLVMCompilerUsed =
      TheModule.getGlobalVariable("llvm.compiler.used");
  findUsedValues(LLVMCompilerUsed, AsmUsed);
  if (LLVMCompilerUsed)
    LLVMCompilerUsed->eraseFromParent();

  if (!AsmUsed.empty()) {
    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext());
    std::vector<Constant *> asmUsed2;
    for (const auto *GV : AsmUsed) {
      Constant *c =
          ConstantExpr::getBitCast(const_cast<GlobalValue *>(GV), i8PTy);
      asmUsed2.push_back(c);
    }

    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
    LLVMCompilerUsed = new llvm::GlobalVariable(
        TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage,
        llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used");

    LLVMCompilerUsed->setSection("llvm.metadata");
  }

  internalizeModule(TheModule, MustPreserveSymbols);
}
<commit_msg>LTOInternalize: Use a StringSet instead of a sorted vector and a binary search query for each function<commit_after>//==-LTOInternalize.cpp - LLVM Link Time Optimizer Internalization Utility -==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a helper to run the internalization part of LTO.
//
//===----------------------------------------------------------------------===//

#include "LTOInternalize.h"

#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Transforms/IPO/Internalize.h"

using namespace llvm;

namespace {
// Helper class that populate the array of symbols used in inlined assembly.
class ComputeAsmUsed {
public:
  ComputeAsmUsed(const StringSet<> &AsmUndefinedRefs, const TargetMachine &TM,
                 const Module &TheModule,
                 SmallPtrSetImpl<const GlobalValue *> &AsmUsed)
      : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), AsmUsed(AsmUsed) {
    accumulateAndSortLibcalls(TheModule);
    for (const Function &F : TheModule)
      findAsmUses(F);
    for (const GlobalVariable &GV : TheModule.globals())
      findAsmUses(GV);
    for (const GlobalAlias &GA : TheModule.aliases())
      findAsmUses(GA);
  }

private:
  // Inputs
  const StringSet<> &AsmUndefinedRefs;
  const TargetMachine &TM;

  // Temps
  llvm::Mangler Mangler;
  StringSet<> Libcalls;

  // Output
  SmallPtrSetImpl<const GlobalValue *> &AsmUsed;

  // Collect names of runtime library functions. User-defined functions with the
  // same names are added to llvm.compiler.used to prevent them from being
  // deleted by optimizations.
  void accumulateAndSortLibcalls(const Module &TheModule) {
    TargetLibraryInfoImpl TLII(Triple(TM.getTargetTriple()));
    TargetLibraryInfo TLI(TLII);

    // TargetLibraryInfo has info on C runtime library calls on the current
    // target.
    for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
         I != E; ++I) {
      LibFunc::Func F = static_cast<LibFunc::Func>(I);
      if (TLI.has(F))
        Libcalls.insert(TLI.getName(F));
    }

    SmallPtrSet<const TargetLowering *, 1> TLSet;

    for (const Function &F : TheModule) {
      const TargetLowering *Lowering =
          TM.getSubtargetImpl(F)->getTargetLowering();

      if (Lowering && TLSet.insert(Lowering).second)
        // TargetLowering has info on library calls that CodeGen expects to be
        // available, both from the C runtime and compiler-rt.
        for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
             I != E; ++I)
          if (const char *Name =
                  Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
            Libcalls.insert(Name);
    }
  }

  void findAsmUses(const GlobalValue &GV) {
    // There are no restrictions to apply to declarations.
    if (GV.isDeclaration())
      return;

    // There is nothing more restrictive than private linkage.
    if (GV.hasPrivateLinkage())
      return;

    SmallString<64> Buffer;
    TM.getNameWithPrefix(Buffer, &GV, Mangler);

    if (AsmUndefinedRefs.count(Buffer))
      AsmUsed.insert(&GV);

    // Conservatively append user-supplied runtime library functions to
    // llvm.compiler.used.  These could be internalized and deleted by
    // optimizations like -globalopt, causing problems when later optimizations
    // add new library calls (e.g., llvm.memset => memset and printf => puts).
    // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
    if (isa<Function>(GV) && Libcalls.count(GV.getName()))
      AsmUsed.insert(&GV);
  }
};

} // namespace anonymous

static void findUsedValues(GlobalVariable *LLVMUsed,
                           SmallPtrSetImpl<const GlobalValue *> &UsedValues) {
  if (!LLVMUsed)
    return;

  ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
  for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
    if (GlobalValue *GV =
            dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
      UsedValues.insert(GV);
}

// mark which symbols can not be internalized
void llvm::LTOInternalize(
    Module &TheModule, const TargetMachine &TM,
    const std::function<bool(const GlobalValue &)> &MustPreserveSymbols,
    const StringSet<> &AsmUndefinedRefs) {
  SmallPtrSet<const GlobalValue *, 8> AsmUsed;
  ComputeAsmUsed(AsmUndefinedRefs, TM, TheModule, AsmUsed);

  GlobalVariable *LLVMCompilerUsed =
      TheModule.getGlobalVariable("llvm.compiler.used");
  findUsedValues(LLVMCompilerUsed, AsmUsed);
  if (LLVMCompilerUsed)
    LLVMCompilerUsed->eraseFromParent();

  if (!AsmUsed.empty()) {
    llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext());
    std::vector<Constant *> asmUsed2;
    for (const auto *GV : AsmUsed) {
      Constant *c =
          ConstantExpr::getBitCast(const_cast<GlobalValue *>(GV), i8PTy);
      asmUsed2.push_back(c);
    }

    llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
    LLVMCompilerUsed = new llvm::GlobalVariable(
        TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage,
        llvm::ConstantArray::get(ATy, asmUsed2), "llvm.compiler.used");

    LLVMCompilerUsed->setSection("llvm.metadata");
  }

  internalizeModule(TheModule, MustPreserveSymbols);
}
<|endoftext|>


<commit_before>/**
* @file SituationPriorProvider.h
*
* @author Benjamin Schlotter
* Implementation of class SituationPriorProvider
*/

#include "SituationPriorProvider.h"

SituationPriorProvider::SituationPriorProvider()
{
  lastRobotState = getPlayerInfo().robotState;
  currentRobotState = getPlayerInfo().robotState;
  gameStateWhenPenalized = GameData::unknown_game_state;
  reasonForLastPenalized = GameData::penalty_none;

  walked_after_penalized_or_init = false;
  wasLiftedUp = false;
}

SituationPriorProvider::~SituationPriorProvider()
{
}

void SituationPriorProvider::execute()
{
  //reset prior
  getSituationPrior().currentPrior = SituationPrior::none;

  // robot state changed
  if(getPlayerInfo().robotState != currentRobotState) {
    lastRobotState = currentRobotState;
    currentRobotState = getPlayerInfo().robotState;

    if(getPlayerInfo().robotState == PlayerInfo::penalized) {
      gameStateWhenPenalized = getGameData().gameState;

      if(getGameData().valid) {
        reasonForLastPenalized = getGameData().getOwnRobotInfo(getPlayerInfo().playerNumber).penalty;
      }
    }
  }

  // calculate walked_after_penalized_or_init
  if( currentRobotState == PlayerInfo::set ||
      currentRobotState == PlayerInfo::initial ||
      currentRobotState == PlayerInfo::penalized)
  {
    walked_after_penalized_or_init = false;
  }
  if(getMotionStatus().currentMotion == motion::walk) {
    walked_after_penalized_or_init = true;
    wasLiftedUp = false;
  }

  //get BodyState
  if(getBodyState().isLiftedUp){
    wasLiftedUp = true;
  }

  // for penalty kicker
  if(getSituationStatus().oppHalf)
  {
    getSituationPrior().currentPrior = SituationPrior::oppHalf;
  }
  //Init Positions and the robot didn't start walking
  else if(currentRobotState == PlayerInfo::ready && lastRobotState == PlayerInfo::initial && !walked_after_penalized_or_init)
  {
    getSituationPrior().currentPrior = SituationPrior::firstReady;
  }
  // treat positioning after penalized
  else if( lastRobotState == PlayerInfo::penalized && !walked_after_penalized_or_init )
  {
    // robot was penalized in set
    //if(gameStateWhenPenalized == GameData::set)
    if(reasonForLastPenalized == GameData::illegal_motion_in_set)
    {
      if(getPlayerInfo().playerNumber == 1) {
        //The Goalie will be in the own Goal if manually placed in set
        getSituationPrior().currentPrior = SituationPrior::goaliePenalizedInSet;
      } else {
        getSituationPrior().currentPrior = SituationPrior::positionedInSet;
      }
    }
    // robot was penalized in game
    else //if (gameStateWhenPenalized == GameData::playing)
    {
      getSituationPrior().currentPrior = SituationPrior::playAfterPenalized;
    }
  }
  //Set
  else if(currentRobotState == PlayerInfo::set)
  {
    getSituationPrior().currentPrior = SituationPrior::set;
  }
}<commit_msg>comment<commit_after>/**
* @file SituationPriorProvider.h
*
* @author Benjamin Schlotter
* Implementation of class SituationPriorProvider
*/

#include "SituationPriorProvider.h"

SituationPriorProvider::SituationPriorProvider()
{
  lastRobotState = getPlayerInfo().robotState;
  currentRobotState = getPlayerInfo().robotState;
  gameStateWhenPenalized = GameData::unknown_game_state;
  reasonForLastPenalized = GameData::penalty_none;

  walked_after_penalized_or_init = false;
  wasLiftedUp = false;
}

SituationPriorProvider::~SituationPriorProvider()
{
}

void SituationPriorProvider::execute()
{
  //reset prior
  getSituationPrior().currentPrior = SituationPrior::none;

  // robot state changed
  if(getPlayerInfo().robotState != currentRobotState) {
    lastRobotState = currentRobotState;
    currentRobotState = getPlayerInfo().robotState;

    if(getPlayerInfo().robotState == PlayerInfo::penalized) {
      gameStateWhenPenalized = getGameData().gameState;

      if(getGameData().valid) {
        reasonForLastPenalized = getGameData().getOwnRobotInfo(getPlayerInfo().playerNumber).penalty;
      }
    }
  }

  // calculate walked_after_penalized_or_init
  if( currentRobotState == PlayerInfo::set ||
      currentRobotState == PlayerInfo::initial ||
      currentRobotState == PlayerInfo::penalized)
  {
    walked_after_penalized_or_init = false;
  }
  if(getMotionStatus().currentMotion == motion::walk) {
    walked_after_penalized_or_init = true;
    wasLiftedUp = false;
  }

  //get BodyState
  if(getBodyState().isLiftedUp){
    wasLiftedUp = true;
  }

  // for penalty kicker, this has the highest priority
  if(getSituationStatus().oppHalf)
  {
    getSituationPrior().currentPrior = SituationPrior::oppHalf;
  }
  //Init Positions and the robot didn't start walking
  else if(currentRobotState == PlayerInfo::ready && lastRobotState == PlayerInfo::initial && !walked_after_penalized_or_init)
  {
    getSituationPrior().currentPrior = SituationPrior::firstReady;
  }
  // treat positioning after penalized
  else if( lastRobotState == PlayerInfo::penalized && !walked_after_penalized_or_init )
  {
    // robot was penalized in set
    //if(gameStateWhenPenalized == GameData::set)
    if(reasonForLastPenalized == GameData::illegal_motion_in_set)
    {
      if(getPlayerInfo().playerNumber == 1) {
        //The Goalie will be in the own Goal if manually placed in set
        getSituationPrior().currentPrior = SituationPrior::goaliePenalizedInSet;
      } else {
        getSituationPrior().currentPrior = SituationPrior::positionedInSet;
      }
    }
    // robot was penalized in game
    else //if (gameStateWhenPenalized == GameData::playing)
    {
      getSituationPrior().currentPrior = SituationPrior::playAfterPenalized;
    }
  }
  //Set
  else if(currentRobotState == PlayerInfo::set)
  {
    getSituationPrior().currentPrior = SituationPrior::set;
  }
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 - 2022, Intel Corporation
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "config.h"

#include "record.hpp"

#include <map>
#include <utility>

#include "geopm/Exception.hpp"
#include "geopm_hint.h"

namespace geopm
{
    std::string event_name(int event_type)
    {
        static const std::map<int, std::string> event_names {
            {EVENT_REGION_ENTRY, "REGION_ENTRY"},
            {EVENT_REGION_EXIT, "REGION_EXIT"},
            {EVENT_EPOCH_COUNT, "EPOCH_COUNT"},
        };
        auto it = event_names.find(event_type);
        if (it == event_names.end()) {
            throw geopm::Exception("unsupported event type: " + std::to_string(event_type),
                                   GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }

    int event_type(const std::string &event_name)
    {
        static const std::map<std::string, int> event_types {
            {"REGION_ENTRY", EVENT_REGION_ENTRY},
            {"REGION_EXIT", EVENT_REGION_EXIT},
            {"EPOCH_COUNT", EVENT_EPOCH_COUNT},
        };
        auto it = event_types.find(event_name);
        if (it == event_types.end()) {
            throw geopm::Exception("invalid event type string: " + event_name,
                                   GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }

    std::string hint_name(uint64_t hint)
    {
        static const std::string hint_names[] = {
            "UNSET",
            "UNKNOWN",
            "COMPUTE",
            "MEMORY",
            "NETWORK",
            "IO",
            "SERIAL",
            "PARALLEL",
            "IGNORE",
            "INACTIVE",
            "SPIN",
        };
        static_assert(sizeof(hint_names) / sizeof(hint_names[0]) ==
                      GEOPM_NUM_REGION_HINT,
                      "hint_names mismatch with geopm_region_hint_e");
        geopm::check_hint(hint);

        return hint_names[hint];
    }

    uint64_t hint_type(const std::string &hint_name)
    {
        static const std::pair<std::string, geopm_region_hint_e>
            hint_mapping[] = {
                std::make_pair("UNSET", GEOPM_REGION_HINT_UNSET),
                std::make_pair("UNKNOWN", GEOPM_REGION_HINT_UNKNOWN),
                std::make_pair("COMPUTE", GEOPM_REGION_HINT_COMPUTE),
                std::make_pair("MEMORY", GEOPM_REGION_HINT_MEMORY),
                std::make_pair("NETWORK", GEOPM_REGION_HINT_NETWORK),
                std::make_pair("IO", GEOPM_REGION_HINT_IO),
                std::make_pair("SERIAL", GEOPM_REGION_HINT_SERIAL),
                std::make_pair("PARALLEL", GEOPM_REGION_HINT_PARALLEL),
                std::make_pair("IGNORE", GEOPM_REGION_HINT_IGNORE),
                std::make_pair("INACTIVE", GEOPM_REGION_HINT_INACTIVE),
                std::make_pair("SPIN", GEOPM_REGION_HINT_SPIN),
            };
        static constexpr unsigned int HINT_MAP_SIZE = sizeof(hint_mapping) /
                                                      sizeof(hint_mapping[0]);
        static_assert(HINT_MAP_SIZE == GEOPM_NUM_REGION_HINT,
                      "hint_mapping mismatch with geopm_region_hint_e");
        static const std::map<std::string, uint64_t>
            result_map(hint_mapping, hint_mapping + HINT_MAP_SIZE);

        auto it = result_map.find(hint_name);
        if (it == result_map.end()) {
            throw Exception("hint_type():  Unknown hint name: " + hint_name + "\n",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }
}
<commit_msg>Added the missing SHORT_REGION record type.<commit_after>/*
 * Copyright (c) 2015 - 2022, Intel Corporation
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "config.h"

#include "record.hpp"

#include <map>
#include <utility>

#include "geopm/Exception.hpp"
#include "geopm_hint.h"

namespace geopm
{
    std::string event_name(int event_type)
    {
        static const std::map<int, std::string> event_names {
            {EVENT_REGION_ENTRY, "REGION_ENTRY"},
            {EVENT_REGION_EXIT, "REGION_EXIT"},
            {EVENT_EPOCH_COUNT, "EPOCH_COUNT"},
            {EVENT_SHORT_REGION, "EVENT_SHORT_REGION"}
        };
        auto it = event_names.find(event_type);
        if (it == event_names.end()) {
            throw geopm::Exception("unsupported event type: " + std::to_string(event_type),
                                   GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }

    int event_type(const std::string &event_name)
    {
        static const std::map<std::string, int> event_types {
            {"REGION_ENTRY", EVENT_REGION_ENTRY},
            {"REGION_EXIT", EVENT_REGION_EXIT},
            {"EPOCH_COUNT", EVENT_EPOCH_COUNT},
            {"EVENT_SHORT_REGION", EVENT_SHORT_REGION}
        };
        auto it = event_types.find(event_name);
        if (it == event_types.end()) {
            throw geopm::Exception("invalid event type string: " + event_name,
                                   GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }

    std::string hint_name(uint64_t hint)
    {
        static const std::string hint_names[] = {
            "UNSET",
            "UNKNOWN",
            "COMPUTE",
            "MEMORY",
            "NETWORK",
            "IO",
            "SERIAL",
            "PARALLEL",
            "IGNORE",
            "INACTIVE",
            "SPIN",
        };
        static_assert(sizeof(hint_names) / sizeof(hint_names[0]) ==
                      GEOPM_NUM_REGION_HINT,
                      "hint_names mismatch with geopm_region_hint_e");
        geopm::check_hint(hint);

        return hint_names[hint];
    }

    uint64_t hint_type(const std::string &hint_name)
    {
        static const std::pair<std::string, geopm_region_hint_e>
            hint_mapping[] = {
                std::make_pair("UNSET", GEOPM_REGION_HINT_UNSET),
                std::make_pair("UNKNOWN", GEOPM_REGION_HINT_UNKNOWN),
                std::make_pair("COMPUTE", GEOPM_REGION_HINT_COMPUTE),
                std::make_pair("MEMORY", GEOPM_REGION_HINT_MEMORY),
                std::make_pair("NETWORK", GEOPM_REGION_HINT_NETWORK),
                std::make_pair("IO", GEOPM_REGION_HINT_IO),
                std::make_pair("SERIAL", GEOPM_REGION_HINT_SERIAL),
                std::make_pair("PARALLEL", GEOPM_REGION_HINT_PARALLEL),
                std::make_pair("IGNORE", GEOPM_REGION_HINT_IGNORE),
                std::make_pair("INACTIVE", GEOPM_REGION_HINT_INACTIVE),
                std::make_pair("SPIN", GEOPM_REGION_HINT_SPIN),
            };
        static constexpr unsigned int HINT_MAP_SIZE = sizeof(hint_mapping) /
                                                      sizeof(hint_mapping[0]);
        static_assert(HINT_MAP_SIZE == GEOPM_NUM_REGION_HINT,
                      "hint_mapping mismatch with geopm_region_hint_e");
        static const std::map<std::string, uint64_t>
            result_map(hint_mapping, hint_mapping + HINT_MAP_SIZE);

        auto it = result_map.find(hint_name);
        if (it == result_map.end()) {
            throw Exception("hint_type():  Unknown hint name: " + hint_name + "\n",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }
}
<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "test/util.hpp"

//m.option("textds").templated<text_t, TextDS<>>();
//template<typename text_t>

/////////////////////////////////
#include <tudocomp/tudocomp.hpp>
class BWTComp : public Compressor {
  public: static Meta meta() {
    Meta m("compressor", "bwt");
    m.option("ds").templated<TextDS<>>();
    m.needs_sentinel_terminator();
    return m; }
  using Compressor::Compressor;
  void compress(Input& in, Output& out) {
    auto o = out.as_stream();
    auto i = in.as_view();
    TextDS<> t(env().env_for_option("ds"),i);
    const auto& sa = t.require_sa();
    for(size_t j = 0; j < t.size(); ++j)
      o << ((sa[j] != 0) ? t[sa[j] - 1]
                         : t[t.size() - 1]);
  }
  void decompress(Input&, Output&){/*[...]*/}
};
/////////////////////////////////

TEST(Bwt, test) {
    auto i = test::compress_input("aaababaaabaababa");
    auto o = test::compress_output();
    auto c = tdc::builder<BWTComp>().instance();
    c.compress(i, o);
    ASSERT_EQ(o.result(), "abb\0ababbaaaaaaaa"_v);
}

/////////////////////////////////
template<class text_t>
class MaxHeapStrategy : public Algorithm {
 public: static Meta meta() {
  Meta m("lcpcomp_strategy", "heap");
  return m; }
 using Algorithm::Algorithm;
 void create_factor(int pos, int src, int len){ /* [...] */ }
 void factorize(text_t& text, const int t) {
  text.require(text_t::SA | text_t::ISA | text_t::LCP);
  auto& sa = text.require_sa();
  auto& isa = text.require_isa();
  auto lcpp = text.release_lcp()->relinquish();
  auto& lcp = *lcpp;
  ArrayMaxHeap<typename text_t::lcp_type::data_type> heap(lcp, lcp.size(), lcp.size());
  for(int i = 1; i < lcp.size(); ++i)
   if(lcp[i] >= t) heap.insert(i);
  while(heap.size() > 0) {
   int m = heap.top(), fpos = sa[m], fsrc = sa[m-1], flen = heap.key(m);
   create_factor(fpos, fsrc, flen);
   for(int k=0; k < flen; k++)
    heap.remove(isa[fpos + k]);
   for(int k=0; k < flen && fpos > k; k++) {
    int s = fpos - k - 1;
    int i = isa[s];
    if(heap.contains(i)) {
     if(s + lcp[i] > fpos) {
      int l = fpos - s;
      if(l >= t)
       heap.decrease_key(i, l);
      else heap.remove(i);
}}}}}};
/////////////////////////////////
TEST(MaxHeap, test) {
    auto text_ds = builder<TextDS<>>().instance("abc\0"_v);
    auto maxheap = builder<MaxHeapStrategy<TextDS<>>>().instance();
    maxheap.factorize(text_ds, 1);
}
<commit_msg>More paper code tests<commit_after>#include "gtest/gtest.h"
#include "test/util.hpp"

//m.option("textds").templated<text_t, TextDS<>>();
//template<typename text_t>

/////////////////////////////////
#include <tudocomp/tudocomp.hpp>
class BWTComp : public Compressor {
  public: static Meta meta() {
    Meta m("compressor", "bwt");
    m.option("ds").templated<TextDS<>>();
    m.needs_sentinel_terminator();
    return m; }
  using Compressor::Compressor;
  void compress(Input& in, Output& out) {
    auto o = out.as_stream();
    auto i = in.as_view();
    TextDS<> t(env().env_for_option("ds"),i);
    const auto& sa = t.require_sa();
    for(size_t j = 0; j < t.size(); ++j)
      o << ((sa[j] != 0) ? t[sa[j] - 1]
                         : t[t.size() - 1]);
  }
  void decompress(Input&, Output&){/*[...]*/}
};
/////////////////////////////////

TEST(SEA17, Bwt) {
    auto i = test::compress_input("aaababaaabaababa");
    auto o = test::compress_output();
    auto c = tdc::builder<BWTComp>().instance();
    c.compress(i, o);
    ASSERT_EQ(o.result(), "abb\0ababbaaaaaaaa"_v);
}

/////////////////////////////////
template<class text_t>
class MaxHeapStrategy : public Algorithm {
 public: static Meta meta() {
  Meta m("lcpcomp_strategy", "heap");
  return m; }
 using Algorithm::Algorithm;
 void create_factor(int pos, int src, int len){ /* [...] */ }
 void factorize(text_t& text, const int t) {
  text.require(text_t::SA | text_t::ISA | text_t::LCP);
  auto& sa = text.require_sa();
  auto& isa = text.require_isa();
  auto lcpp = text.release_lcp()->relinquish();
  auto& lcp = *lcpp;
  ArrayMaxHeap<typename text_t::lcp_type::data_type> heap(lcp, lcp.size(), lcp.size());
  for(int i = 1; i < lcp.size(); ++i)
   if(lcp[i] >= t) heap.insert(i);
  while(heap.size() > 0) {
   int m = heap.top(), fpos = sa[m], fsrc = sa[m-1], flen = heap.key(m);
   create_factor(fpos, fsrc, flen);
   for(int k=0; k < flen; k++)
    heap.remove(isa[fpos + k]);
   for(int k=0; k < flen && fpos > k; k++) {
    int s = fpos - k - 1;
    int i = isa[s];
    if(heap.contains(i)) {
     if(s + lcp[i] > fpos) {
      int l = fpos - s;
      if(l >= t)
       heap.decrease_key(i, l);
      else heap.remove(i);
}}}}}};
/////////////////////////////////
TEST(SEA17, MaxHeap) {
    auto text_ds = builder<TextDS<>>().instance("abc\0"_v);
    auto maxheap = builder<MaxHeapStrategy<TextDS<>>>().instance();
    maxheap.factorize(text_ds, 1);
}
/////////////////////////////////
void factorize(TextDS<>& T, SuffixTree& ST, std::function<void(int begin, int end, int ref)> output){
 typedef SuffixTree::node_type node_t;
 sdsl::int_vector<> R(ST.internal_nodes,0,bits_for(T.size() * bits_for(ST.cst.csa.sigma) / bits_for(T.size())));
 int pos = 0, z = 0;
 while(pos < T.size() - 1) {
  node_t l = ST.select_leaf(ST.cst.csa.isa[pos]);
  int leaflabel = pos;
  if(ST.parent(l) == ST.root || R[ST.nid(ST.parent(l))] != 0) {
   int parent_strdepth = ST.str_depth(ST.parent(l));
   output(pos + parent_strdepth, pos + parent_strdepth + 1, R[ST.nid(ST.parent(l))]);
   pos += parent_strdepth+1;
   ++z;
   continue;
  }
  int d = 1;
  node_t parent = ST.root;
  node_t node = ST.level_anc(l, d);
  while(R[ST.nid(node)] != 0) {
   parent = node;
   node = ST.level_anc(l, ++d);
  }
  pos += ST.str_depth(parent);
  int begin = leaflabel + ST.str_depth(parent);
  int end = leaflabel + ST.str_depth(node);
  output(begin, end, R[ST.nid(ST.parent(node))]);
  R[ST.nid(node)] = ++z;
  pos += end - begin;
 }
}
/////////////////////////////////
TEST(SEA17, factorize) {
    auto T = "aaababaaabaababa\0"_v;
    auto text_ds = builder<TextDS<>>().instance(T);
    std::vector<int> v;
    auto f = [&](int begin, int end, int ref) {
        v.push_back(begin);
        v.push_back(end);
        v.push_back(ref);
    };
    SuffixTree::cst_t backing_cst;
    {
        std::string bad_copy_1 = T.slice(0, T.size() - 1);
        construct_im(backing_cst, bad_copy_1, 1);
    }
    SuffixTree ST(backing_cst);

    factorize(text_ds, ST,f);

    ASSERT_EQ(v, (std::vector<int> {
        0,   1,   0,
        2,   3,   1,
        3,   5,   0,
        7,   8,   3,
        9,  11,   1,
        14, 16,   5,
        // 16, 17,   0,
    }));
}
<|endoftext|>


<commit_before>/*
Copyright 2016 Colin Girling

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#ifndef OCL_GUARD_TEST_TESTSTRINGUTILITY_HPP
#define OCL_GUARD_TEST_TESTSTRINGUTILITY_HPP

#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include "TestMemoryUtility.hpp"
#include "TestConverterUtility.hpp"

namespace ocl
{

/*
    String utility class providing features such as:
        allocation, de-allocation, filling, copying, appending

    Functions that don't do pointer checking start with Unsafe in the name.
*/

struct TestStringUtility
{
    // NOTE: size_type is not used as it causes
    // possible loss of data warnings for some compilers.
    typedef unsigned int size_type;

    template<typename IntType>
    static char const* GetMinSignedIntAsString(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return "-128";
            case 2: return "-32768";
            case 4: return "-2147483648";
            case 8: return "-9223372036854775808";
        }

        return "";
    }

    template<typename IntType>
    static char const* GetMaxSignedIntAsString(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return "127";
            case 2: return "32767";
            case 4: return "2147483647";
            case 8: return "9223372036854775807";
        }

        return "";
    }

    template<typename IntType>
    static char const* GetMaxUnsignedIntAsString(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return "255";
            case 2: return "65535";
            case 4: return "4294967295";
            case 8: return "18446744073709551615";
        }

        return "";
    }

    template<typename IntType>
    static size_type GetMinSignedIntCharCount(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return 4U;
            case 2: return 6U;
            case 4: return 11U;
            case 8: return 20U;
        }

        return 0U;
    }

    template<typename IntType>
    static size_type GetMaxSignedIntCharCount(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return 3U;
            case 2: return 5U;
            case 4: return 10U;
            case 8: return 19U;
        }

        return 0U;
    }

    template<typename IntType>
    static size_type GetMaxUnsignedIntCharCount(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return 3U;
            case 2: return 5U;
            case 4: return 10U;
            case 8: return 20U;
        }

        return 0U;
    }

    template<typename T>
    static char* GetString(T value)
    {
        size_type len = 0U;
        return TestConverterUtility<T>::GetString(value, len);
    }

    template<typename Type, typename SizeType>
    static char* GetString(Type value, SizeType& length)
    {
        return TestConverterUtility<Type, SizeType>::GetString(value, length);
    }

    static void UnsafeFill(char* str, char ch, size_type len)
    {
        char* end = str + len;
        for (; str < end; ++str)
            *str = ch;
        *str = '\0';
    }

    static size_type SafeLength(char const* str)
    {
        size_type len = str != NULL ? static_cast<size_type>(::strlen(str)) : 0U;
        return len;
    }

    static bool UnsafeFind(char const* str, char ch, size_type& pos, size_type start = 0)
    {
        char const* pch = str + start;
        for (; (*pch != '\0') && (*pch != ch); ++pch)
            ;
        if ((ch != '\0') && (*pch == '\0'))
            return false;
        pos = static_cast<size_type>(pch - str);
        return true;
    }

    static void Allocate(char*& dest, size_type dest_len)
    {
        dest = TestMemoryUtility<char>::Allocate(dest_len + 1);
    }

    static void FastFree(char* str)
    {
        TestMemoryUtility<char>::FastFree(str);
    }

    static void SafeFree(char*& str)
    {
        TestMemoryUtility<char>::SafeFree(str);
    }

    static void SafeAllocateCopy(char*& dest,
                                 size_type& dest_len,
                                 char const* src,
                                 size_type src_len)
    {
        if ((src != NULL) && (src_len > 0))
        {
            dest = TestMemoryUtility<char>::UnsafeAllocateCopy(src, src_len + 1);
            dest_len = (dest != NULL) ? src_len : static_cast<size_type>(0);

            // If src is longer than src_len, add the terminating '\0'.
            if (*(src + src_len) != '\0')
                *(dest + dest_len) = '\0';
        }
        else
        {
            dest = NULL;
            dest_len = 0;
        }
    }

    static void SafeAllocateCopy(char*& dest, size_type& dest_len, char const* src)
    {
        if (src == NULL)
        {
            dest = NULL;
            dest_len = 0;
        }
        else
            UnsafeAllocateCopy(dest, dest_len, src);
    }

    static void UnsafeAllocateCopy(char*& dest, size_type& dest_len, char const* src)
    {
        size_type src_len = static_cast<size_type>(::strlen(src));
        dest = TestMemoryUtility<char>::UnsafeAllocateCopy(src, src_len + 1);
        dest_len = (dest != NULL) ? src_len : static_cast<size_type>(0);
    }

    static void SafeReallocCopy(char*& dest, size_type& dest_len, char const* src)
    {
        FastFree(dest);
        SafeAllocateCopy(dest, dest_len, src);
    }

    static void SafeReallocCopy(char*& dest,
                                size_type& dest_len,
                                char const* src,
                                size_type src_len)
    {
        FastFree(dest);
        SafeAllocateCopy(dest, dest_len, src, src_len);
    }

    /// Allocate enough space in dest to copy str1 and append str2.
    /// @note It is safe for dest and str1 or str2 to be the same string.
    /// Also str1 or str2 can be NULL.
    static void SafeAllocAppend(char*& dest,
                                size_type& dest_len,
                                char const* str1,
                                size_type str1_len,
                                char const* str2,
                                size_type str2_len)
    {
        size_type new_len = str1_len + str2_len;
        if (new_len > 0)
        {
            char* new_dest = NULL;
            Allocate(new_dest, new_len);
            if (new_dest != NULL)
            {
                if ((str1 != NULL) && (str1_len > 0))
                    ::memcpy(new_dest, str1, str1_len);
                else
                {
                    new_len -= str1_len;
                    str1_len = 0;
                }
                if ((str2 != NULL) && (str2_len > 0))
                    ::memcpy(new_dest + str1_len, str2, str2_len);
                else
                    new_len -= str2_len;
                *(new_dest + new_len) = '\0';
                dest_len = new_len;
            }
            else
                dest_len = 0;
            FastFree(dest);
            dest = new_dest;
        }
        else
        {
            dest = NULL;
            dest_len = 0;
        }
    }

    /// Same as AllocAppend, except dest is first freed
    /// before being set with str1 and str2.
    static void SafeReallocAppend(char*& dest,
                                  size_type& dest_len,
                                  char const* str1,
                                  size_type str1_len,
                                  char const* str2,
                                  size_type str2_len)
    {
        char* new_dest = NULL;
        size_type new_dest_len = 0;
        SafeAllocAppend(new_dest, new_dest_len, str1, str1_len, str2, str2_len);
        FastFree(dest);
        dest = new_dest;
        dest_len = new_dest_len;
    }
};

} // namespace ocl

#endif // OCL_GUARD_TEST_TESTSTRINGUTILITY_HPP
<commit_msg>Changed function ording to be consistent with other functions in TestStringUtility class.<commit_after>/*
Copyright 2016 Colin Girling

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#ifndef OCL_GUARD_TEST_TESTSTRINGUTILITY_HPP
#define OCL_GUARD_TEST_TESTSTRINGUTILITY_HPP

#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include "TestMemoryUtility.hpp"
#include "TestConverterUtility.hpp"

namespace ocl
{

/*
    String utility class providing features such as:
        allocation, de-allocation, filling, copying, appending

    Functions that don't do pointer checking start with Unsafe in the name.
*/

struct TestStringUtility
{
    // NOTE: size_type is not used as it causes
    // possible loss of data warnings for some compilers.
    typedef unsigned int size_type;

    template<typename IntType>
    static char const* GetMinSignedIntAsString(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return "-128";
            case 2: return "-32768";
            case 4: return "-2147483648";
            case 8: return "-9223372036854775808";
        }

        return "";
    }

    template<typename IntType>
    static char const* GetMaxSignedIntAsString(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return "127";
            case 2: return "32767";
            case 4: return "2147483647";
            case 8: return "9223372036854775807";
        }

        return "";
    }

    template<typename IntType>
    static char const* GetMaxUnsignedIntAsString(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return "255";
            case 2: return "65535";
            case 4: return "4294967295";
            case 8: return "18446744073709551615";
        }

        return "";
    }

    template<typename IntType>
    static size_type GetMinSignedIntCharCount(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return 4U;
            case 2: return 6U;
            case 4: return 11U;
            case 8: return 20U;
        }

        return 0U;
    }

    template<typename IntType>
    static size_type GetMaxSignedIntCharCount(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return 3U;
            case 2: return 5U;
            case 4: return 10U;
            case 8: return 19U;
        }

        return 0U;
    }

    template<typename IntType>
    static size_type GetMaxUnsignedIntCharCount(IntType size_of_int) throw()
    {
        switch (size_of_int)
        {
            case 1: return 3U;
            case 2: return 5U;
            case 4: return 10U;
            case 8: return 20U;
        }

        return 0U;
    }

    template<typename T>
    static char* GetString(T value)
    {
        size_type len = 0U;
        return TestConverterUtility<T>::GetString(value, len);
    }

    template<typename Type, typename SizeType>
    static char* GetString(Type value, SizeType& length)
    {
        return TestConverterUtility<Type, SizeType>::GetString(value, length);
    }

    static void UnsafeFill(char* str, char ch, size_type len)
    {
        char* end = str + len;
        for (; str < end; ++str)
            *str = ch;
        *str = '\0';
    }

    static size_type SafeLength(char const* str)
    {
        size_type len = str != NULL ? static_cast<size_type>(::strlen(str)) : 0U;
        return len;
    }

    static bool UnsafeFind(char const* str, char ch, size_type& pos, size_type start = 0)
    {
        char const* pch = str + start;
        for (; (*pch != '\0') && (*pch != ch); ++pch)
            ;
        if ((ch != '\0') && (*pch == '\0'))
            return false;
        pos = static_cast<size_type>(pch - str);
        return true;
    }

    static void Allocate(char*& dest, size_type dest_len)
    {
        dest = TestMemoryUtility<char>::Allocate(dest_len + 1);
    }

    static void FastFree(char* str)
    {
        TestMemoryUtility<char>::FastFree(str);
    }

    static void SafeFree(char*& str)
    {
        TestMemoryUtility<char>::SafeFree(str);
    }

    static void SafeAllocateCopy(char*& dest,
                                 size_type& dest_len,
                                 char const* src,
                                 size_type src_len)
    {
        if ((src != NULL) && (src_len > 0))
        {
            dest = TestMemoryUtility<char>::UnsafeAllocateCopy(src, src_len + 1);
            dest_len = (dest != NULL) ? src_len : static_cast<size_type>(0);

            // If src is longer than src_len, add the terminating '\0'.
            if (*(src + src_len) != '\0')
                *(dest + dest_len) = '\0';
        }
        else
        {
            dest = NULL;
            dest_len = 0;
        }
    }

    static void SafeAllocateCopy(char*& dest, size_type& dest_len, char const* src)
    {
        if (src == NULL)
        {
            dest = NULL;
            dest_len = 0;
        }
        else
            UnsafeAllocateCopy(dest, dest_len, src);
    }

    static void UnsafeAllocateCopy(char*& dest, size_type& dest_len, char const* src)
    {
        size_type src_len = static_cast<size_type>(::strlen(src));
        dest = TestMemoryUtility<char>::UnsafeAllocateCopy(src, src_len + 1);
        dest_len = (dest != NULL) ? src_len : static_cast<size_type>(0);
    }

    static void SafeReallocCopy(char*& dest,
                                size_type& dest_len,
                                char const* src,
                                size_type src_len)
    {
        FastFree(dest);
        SafeAllocateCopy(dest, dest_len, src, src_len);
    }

    static void SafeReallocCopy(char*& dest, size_type& dest_len, char const* src)
    {
        FastFree(dest);
        SafeAllocateCopy(dest, dest_len, src);
    }

    /// Allocate enough space in dest to copy str1 and append str2.
    /// @note It is safe for dest and str1 or str2 to be the same string.
    /// Also str1 or str2 can be NULL.
    static void SafeAllocAppend(char*& dest,
                                size_type& dest_len,
                                char const* str1,
                                size_type str1_len,
                                char const* str2,
                                size_type str2_len)
    {
        size_type new_len = str1_len + str2_len;
        if (new_len > 0)
        {
            char* new_dest = NULL;
            Allocate(new_dest, new_len);
            if (new_dest != NULL)
            {
                if ((str1 != NULL) && (str1_len > 0))
                    ::memcpy(new_dest, str1, str1_len);
                else
                {
                    new_len -= str1_len;
                    str1_len = 0;
                }
                if ((str2 != NULL) && (str2_len > 0))
                    ::memcpy(new_dest + str1_len, str2, str2_len);
                else
                    new_len -= str2_len;
                *(new_dest + new_len) = '\0';
                dest_len = new_len;
            }
            else
                dest_len = 0;
            FastFree(dest);
            dest = new_dest;
        }
        else
        {
            dest = NULL;
            dest_len = 0;
        }
    }

    /// Same as AllocAppend, except dest is first freed
    /// before being set with str1 and str2.
    static void SafeReallocAppend(char*& dest,
                                  size_type& dest_len,
                                  char const* str1,
                                  size_type str1_len,
                                  char const* str2,
                                  size_type str2_len)
    {
        char* new_dest = NULL;
        size_type new_dest_len = 0;
        SafeAllocAppend(new_dest, new_dest_len, str1, str1_len, str2, str2_len);
        FastFree(dest);
        dest = new_dest;
        dest_len = new_dest_len;
    }
};

} // namespace ocl

#endif // OCL_GUARD_TEST_TESTSTRINGUTILITY_HPP
<|endoftext|>


<commit_before>// Includes
#include <Windows.h>
#include "NuiApi.h"
#include "cinder/app/AppBasic.h"
#include "cinder/Camera.h"
#include "cinder/gl/Texture.h"
#include "cinder/gl/TextureFont.h"
#include "cinder/ImageIo.h"
#include "cinder/params/Params.h"
#include "cinder/Utilities.h"
#include "cinder/gl/gl.h"
#include "cinder/Text.h"
#include "moduleCapture.h"
#include "moduleProcessing.h"
#include "modulePresentation.h"

class AirGuitarApp : public ci::app::AppBasic
{

public:

	// Cinder callbacks
	void	draw();
	void	keyDown( ci::app::KeyEvent event );
	void	prepareSettings( ci::app::AppBasic::Settings *settings );
	void	setup();
	void	shutdown();
	void	update();

	moduleCapture capture;

private:
	modulePresentation mPresentation;
	moduleProcessing mProcessing;
	HandsHip *handsHip;

	ci::gl::TextureFontRef mFont;
	ci::gl::Texture *backgroundTex;
	ci::gl::Texture guitar;
	std::string mText;
	point chordHandPos;
	point playHandPos;
	point HipPos;
};

// Imports
using namespace ci;
using namespace ci::app;
using namespace std;

// Render
void AirGuitarApp::draw()
{
	ci::gl::clear();
	if(backgroundTex != NULL){
		gl::draw(*backgroundTex, getWindowBounds());
	}
	mFont->drawString(mText, cinder::Rectf(0,0,800,200));
	if(handsHip != NULL){
		mPresentation.drawGuitar(guitar, HipPos, chordHandPos);
		ci::gl::drawSolidCircle( Vec2f( chordHandPos.x, chordHandPos.y), 10);
		ci::gl::drawSolidCircle( Vec2f( playHandPos.x, playHandPos.y), 10);
		ci::gl::drawSolidCircle( Vec2f( HipPos.x, HipPos.y), 10);
	}
}

// Handles key press
void AirGuitarApp::keyDown( KeyEvent event )
{

	// Quit, toggle fullscreen
	switch ( event.getCode() ) {
	case KeyEvent::KEY_q:
		quit();
		break;
	case KeyEvent::KEY_f:
		setFullScreen( !isFullScreen() );
		break;
	}
}

// Prepare window
void AirGuitarApp::prepareSettings( Settings *settings )
{
        settings->setWindowSize( 800, 600 );
        settings->setFrameRate( 60.0f );
}

// Set up
void AirGuitarApp::setup(){
	mFont = ci::gl::TextureFont::create(Font("Arial Black", 40));
	mText = "durr";
	capture = moduleCapture();
	backgroundTex = NULL;
	mPresentation.setSounds(0);
	guitar = loadImage(getAssetPath("electric/image/electric_right.png"));
	OutputDebugStringW(L"In setup end\n");
}

// Called on exit
void AirGuitarApp::shutdown()
{
}

// Runs update logic
void AirGuitarApp::update()
{
	handsHip = capture.formHandsHip(0);

	if(handsHip != NULL){
		mProcessing.calculateVolume(handsHip);
		mProcessing.calculateTone(handsHip);
		if(mProcessing.playedNote(handsHip)){
			mPresentation.playNote(mProcessing.tone,mProcessing.volume);
		}
		chordHandPos = capture.SkeletonPointToScreen(handsHip->chordHandPosition, ci::app::getWindowHeight(), ci::app::getWindowWidth());
		playHandPos = capture.SkeletonPointToScreen(handsHip->playingHandPosition, ci::app::getWindowHeight(), ci::app::getWindowWidth());
		HipPos = capture.SkeletonPointToScreen(handsHip->hipPosition, ci::app::getWindowHeight(), ci::app::getWindowWidth());
		mText = std::to_string(mProcessing.tone);
	} else {
		mText = "Skeleton not found";
	}
	ci::gl::Texture *tmp = capture.getNextFrame();
	if (tmp != NULL){
		backgroundTex = tmp;
	}
}

// Run application
CINDER_APP_BASIC( AirGuitarApp, RendererGl )<commit_msg>Fixed conflicts<commit_after>// Includes
#include <Windows.h>
#include "cinder/app/AppBasic.h"
#include "cinder/Camera.h"
#include "cinder/gl/Texture.h"
#include "cinder/gl/TextureFont.h"
#include "cinder/ImageIo.h"
#include "cinder/params/Params.h"
#include "cinder/Utilities.h"
#include "cinder/gl/gl.h"
#include "cinder/Text.h"
#include "NuiApi.h"
#include "moduleCapture.h"
#include "moduleProcessing.h"
#include "modulePresentation.h"
#include "ciUI.h"
/*
* This application demonstrates how to acquire and display
* skeleton data.
*/
class AirGuitarApp : public ci::app::AppBasic
{

public:

	// Cinder callbacks
	void	draw();
	void	keyDown( ci::app::KeyEvent event );
//	void	prepareSettings( ci::app::AppBasic::Settings *settings );
	void	setup();
	void	shutdown();
	void	update();
	void	guiEvent(ciUIEvent *event);

	moduleCapture capture;

private:
	modulePresentation mPresentation;
	moduleProcessing mProcessing;
	HandsHip *handsHip;
	float guiWidth;
    float guiHeight;
    float dim;
    float length;
	ci::gl::Texture *backgroundTex;
	ci::gl::Texture guitar;
	std::string mText;
	point chordHandPos;
	point playHandPos;
	point HipPos;
    ColorA backgroundColor;
    ciUICanvas *gui;
	int instrument;
	bool rightHanded;
};

// Imports
using namespace ci;
using namespace ci::app;
using namespace std;

// Render
void AirGuitarApp::draw()
{
	ci::gl::clear(backgroundColor);

	if(backgroundTex != NULL){
		gl::draw(*backgroundTex, getWindowBounds());
	}
	if(handsHip != NULL){
		mPresentation.drawGuitar(guitar, HipPos, chordHandPos);
		ci::gl::drawSolidCircle( Vec2f( chordHandPos.x, chordHandPos.y), 10);
		ci::gl::drawSolidCircle( Vec2f( playHandPos.x, playHandPos.y), 10);
		ci::gl::drawSolidCircle( Vec2f( HipPos.x, HipPos.y), 10);
	}
	 gl::enableAlphaBlending();
	 gui->draw();
	 gl::disableAlphaBlending();
//	mFont->drawString(mText, cinder::Rectf(0,0,800,200));
}

// Handles key press
void AirGuitarApp::keyDown( KeyEvent event )
{

	// Quit, toggle fullscreen
	switch ( event.getCode() ) {
	case KeyEvent::KEY_q:
		quit();
		break;
	case KeyEvent::KEY_f:
		setFullScreen( !isFullScreen() );
		break;
	case KeyEvent::KEY_SPACE:
		/*if(mText == "hejsan"){
			mText = "apfan";
		} else {
			mText = "hejsan";
		}*/
		break;
	}
}

// Prepare window
/*void AirGuitarApp::prepareSettings( Settings *settings )
{
        settings->setWindowSize( 800, 600 );
        settings->setFrameRate( 60.0f );
}*/

// Set up
void AirGuitarApp::setup(){
	backgroundTex = NULL;

    backgroundColor = ColorA(233.0/255.0, 52.0/255.0, 27.0/255.0);
    guiWidth = getWindowWidth()*.4;
    guiHeight= getWindowHeight()*.75;
    dim = guiWidth*.0625;
    length = guiWidth-CI_UI_GLOBAL_WIDGET_SPACING*2;

	rightHanded = true;

	vector<string> instruments;
	instruments.push_back("Electric Guitar");
	instruments.push_back("Bass");

	vector<string> handedness;
	handedness.push_back("Right");
	handedness.push_back("Left");

    gui = new ciUICanvas(10,10,guiWidth, guiHeight);
	gui->addWidgetDown(new ciUILabel(0,25, "AIRGUITAR", CI_UI_FONT_MEDIUM));
	gui->addWidgetDown(new ciUISlider(length - CI_UI_GLOBAL_WIDGET_SPACING, dim, 0.0, 1.0, 1.0, "Volume"));
	gui->addWidgetDown(new ciUIRadio(20.0,20.0,"Instrument",instruments,0));
	((ciUIRadio *) gui->getWidget("Instrument"))->activateToggle("Electric Guitar");
	gui->addWidgetDown(new ciUIRadio(20.0,20.0,"Handedness",handedness,0));
	((ciUIRadio *) gui->getWidget("Handedness"))->activateToggle("Right");

    gui->registerUIEvents(this, &AirGuitarApp::guiEvent);

	capture = moduleCapture();
	mPresentation.setSounds(0);
	guitar = loadImage(getAssetPath("electric/image/electric_right.png"));
	OutputDebugStringW(L"In setup end\n");
}

void AirGuitarApp::guiEvent(ciUIEvent *event){
	string name = event->widget->getName();

	if(name == "Volume")
	{
		ciUISlider *slider = (ciUISlider *) event->widget;
		mPresentation.globalVolume = slider->getScaledValue();
	}
	if(name == "Electric Guitar")
	{
		mPresentation.setSounds(0);
	}
	if(name == "Bass")
	{
		mPresentation.setSounds(1);
	}
	if(name == "Right")
	{
		rightHanded = true;
	}
	if(name == "Left")
	{
		rightHanded = false;
	}
}

// Called on exit
void AirGuitarApp::shutdown()
{
}

// Runs update logic
void AirGuitarApp::update()
{

	gui->update();
	handsHip = capture.formHandsHip(0,rightHanded);
	if(handsHip != NULL){
		/*mText = std::to_string(handsHip->chordHandPosition.x) + ", " + std::to_string(handsHip->chordHandPosition.y) + ", " + std::to_string(handsHip->chordHandPosition.z);
		mText += "\n";
		mText += std::to_string(handsHip->playingHandPosition.x) + ", " + std::to_string(handsHip->playingHandPosition.y) + ", " + std::to_string(handsHip->playingHandPosition.z);
		mText += "\n";
		mText += std::to_string(handsHip->hipPosition.x) + ", " + std::to_string(handsHip->hipPosition.y) + ", " + std::to_string(handsHip->hipPosition.z);
		mText += "\n";*/
		mProcessing.calculateVolume(handsHip);
		mProcessing.calculateTone(handsHip);
		if(mProcessing.playedNote(handsHip)){
			mPresentation.playNote(mProcessing.tone,mProcessing.volume);
		}
		//mText += std::to_string(mProcessing.tone);
	} else {
		//mText = "Skeleton not found";
	}
	ci::gl::Texture *tmp = capture.getNextFrame();
	if (tmp != NULL){
		backgroundTex = tmp;
	}
}

// Run application
CINDER_APP_BASIC( AirGuitarApp, RendererGl )<|endoftext|>