<commit_before>#include "CommandLineAndConfig.h"
#include "boost/filesystem.hpp"
#include <iostream>
#include "ExitCodes.h"
#include "Loggers.h"

using namespace boost::program_options;

#include "sbu.h"

int CommandLineAndOptions::ParseOptions(int argc, const char* argv[])
{
	int retValue = ExitCode_Success;

	const std::string configFileEnvVar = "SBU_CONFIG";
	options_description desc("Allowed options");

	std::string path;
	std::string name;
	std::string action;
	std::string date;
	std::string config_file;
	std::string logging;
	std::string logging_verbosity;
	std::string workdir;
	std::string filerepName;
	std::string filerepPath;
	std::string repPath;
	std::string backupDBPath;
	std::string bstep;
	std::string rstep;
	std::string filerepPassword;
	std::string awskey, awssecret, awsbucket, awsregion, awsBasePath;
	std::string storageType;
	int byID;
	long maxSizeToBulk;
	long bulkSize;

	desc.add_options()
		("help,h", "print usage message")
		("version", "print version")
		("config", value(&config_file), "Config file")
		("General.Workdir", value(&workdir), "working dir of the cmd")
		("action,a", value(&action), "Actions include : CreateBackupDef, ListBackupDef, Backup, Restore, ListBackup, BackupInfo")
		("name,n", value(&name), "Name")
		("path,p", value(&path), "Path")
		("byID", value(&byID), "Select By ID")
		("bstep", value(&bstep), "BackupStep : All, Init, Scan, DiffCalc, FileUpload, Complete")
		("rstep", value(&rstep), "RestoreStep: Init, Scan, DiffCalc, Download, Complete")
		("date,d", value(&date), "The last effective date - Defaults to now()")
		("General.StorageType", value(&filerepPassword), "StorageType: FileRepository, SecureFileRepository, AwsS3, SecureAwsS3")
		("Storage.password", value(&storageType), "If exists uses this password SecureFileRepository or S3 Client side encryption")
		("FileRepository.name", value(&filerepName)->default_value("FileRepository.db"), "The database name of the FileRepository")
		("FileRepository.path", value(&filerepPath), "Path of the FileRepository")
		("FileRepository.maxSizeToBulk", value(&maxSizeToBulk)->default_value(128 * 1024), "Minimum file size to bulk")
		("FileRepository.bulkSize", value(&bulkSize)->default_value(5 * 1024 * 1024), "bulk Size")
		("AwsS3Storage.key", value(&awskey), "Access key for the AWS Account")
		("AwsS3Storage.secret", value(&awssecret), "Secret for the AWS Account")
		("AwsS3Storage.bucket", value(&awsbucket), "S3 Bucket AWS Account")
		("AwsS3Storage.region", value(&awsregion), "S3 Bucket region AWS Account")
		("AwsS3Storage.path", value(&awsBasePath), "S3 BasePath in Bucket AWS Account")
		("Logging.Console", value(&logging)->default_value("False"), "true/false - Enable logs to console")
		("Logging.FileOutput", value(&logging), "filename - if exists emit logs to the file")
		("Logging.Verbosity", value(&logging_verbosity)->default_value("Information"), "Logging Verbosity - Default Info")
		("Repository.path", value(&repPath)->default_value("RepositoryDB.db"), "RepositoryDB path")
		("showOnly", "In restore show only the files to be restored")
		("BackupDB.path", value(&backupDBPath)->default_value("BackupDB.db"), "The name of the Backup database to use")
		;

	try
	{
		store(parse_command_line(argc, argv, desc), vm);
		std::string sbuConfigFileName;

		char* configFile = std::getenv(configFileEnvVar.c_str());
		if (configFile != NULL)
		{
			sbuConfigFileName = configFile;
		}

		if (!vm["config"].empty())
		{
			sbuConfigFileName = vm["config"].as<std::string>();
		}

		if (!sbuConfigFileName.empty())
		{
			if (boost::filesystem::exists(sbuConfigFileName))
			{
				auto fileParams = parse_config_file<char>(sbuConfigFileName.c_str(), desc, true);
				for (const auto& o : fileParams.options) {
					const std::string logComponentPrefix = "Logging.Components.";
					if (o.string_key.rfind(logComponentPrefix, 0) == 0)
					{
						LoggingComponentEntry entry;
						entry.componentName = o.string_key.substr(logComponentPrefix.size());
						entry.level = o.value[0];
						loggingOptions.components.push_back(entry);
					}

				}
				store(fileParams, vm);
			}
			else
			{
				return ExitCode_ConfigFileMissing;
			}
		}

		store(parse_environment(desc,
			[](const std::string& i_env_var)
			{// maps environment variable "HOSTNAME" to user-defined option "hostname"
				return i_env_var == "HOSTNAME" ? "hostname" : "";
			}),
			vm);

		if (!vm["help"].empty() || !vm["version"].empty())
		{
			std::cout << std::string("sbu ( Smart Backup Utility ) : ") + g_Version << std::endl;
			std::cout << std::string("Written by ") << std::string(g_DeveloperName) << std::endl;

			if (!vm["help"].empty())
			{
				std::cout << desc << std::endl;
				return ExitCode_HelpCalled;
			}
			else
			{
				return ExitCode_VersionCalled;
			}
		}

		if (vm["action"].empty())
		{
			std::cout << "Missing action argument" << std::endl;
			return ExitCode_MissingAction;
		}
	}
	catch (const boost::program_options::unknown_option exception)
	{
		std::cout << std::string("Invalid option ") << exception.get_option_name() << std::endl;
		retValue = ExitCode_InvalidArgument;
	}

	return retValue;
}
<commit_msg>moved default values to top<commit_after>#include "CommandLineAndConfig.h"
#include "boost/filesystem.hpp"
#include <iostream>
#include "ExitCodes.h"
#include "Loggers.h"

using namespace boost::program_options;

#include "sbu.h"

int CommandLineAndOptions::ParseOptions(int argc, const char* argv[])
{
	int retValue = ExitCode_Success;

	const std::string configFileEnvVar = "SBU_CONFIG";
	options_description desc("Allowed options");

	std::string path;
	std::string name;
	std::string action;
	std::string date;
	std::string config_file;
	std::string logging;
	std::string logging_verbosity;
	std::string workdir;
	std::string filerepName;
	std::string filerepPath;
	std::string repPath;
	std::string backupDBPath;
	std::string bstep;
	std::string rstep;
	std::string filerepPassword;
	std::string awskey, awssecret, awsbucket, awsregion, awsBasePath;
	std::string storageType;
	int byID;
	long maxSizeToBulk;
	long bulkSize;

	const long maxSizeToBulkDefault = 128 * 1024;
	const long bulkSizeDefault = 5 * 1024 * 1024;
	const std::string shouldLogToConsole = "False";
	const std::string rootLogLevel = "Information";
	const std::string repositoryDB = "RepositoryDB.db";
	const std::string backupDB = "BackupDB.db";
	const std::string fileRepositoryDB = "FileRepositoryDB.db";

	desc.add_options()
		("help,h", "print usage message")
		("version", "print version")
		("config", value(&config_file), "Config file")
		("General.Workdir", value(&workdir), "working dir of the cmd")
		("action,a", value(&action), "Actions include : CreateBackupDef, ListBackupDef, Backup, Restore, ListBackup, BackupInfo")
		("name,n", value(&name), "Name")
		("path,p", value(&path), "Path")
		("byID", value(&byID), "Select By ID")
		("bstep", value(&bstep), "BackupStep : All, Init, Scan, DiffCalc, FileUpload, Complete")
		("rstep", value(&rstep), "RestoreStep: Init, Scan, DiffCalc, Download, Complete")
		("date,d", value(&date), "The last effective date - Defaults to now()")
		("General.StorageType", value(&filerepPassword), "StorageType: FileRepository, SecureFileRepository, AwsS3, SecureAwsS3")
		("Storage.password", value(&storageType), "If exists uses this password SecureFileRepository or S3 Client side encryption")
		("FileRepository.name", value(&filerepName)->default_value(fileRepositoryDB), "The database name of the FileRepository")
		("FileRepository.path", value(&filerepPath), "Path of the FileRepository")
		("FileRepository.maxSizeToBulk", value(&maxSizeToBulk)->default_value(maxSizeToBulkDefault), "Minimum file size to bulk")
		("FileRepository.bulkSize", value(&bulkSize)->default_value(bulkSizeDefault), "bulk Size")
		("AwsS3Storage.key", value(&awskey), "Access key for the AWS Account")
		("AwsS3Storage.secret", value(&awssecret), "Secret for the AWS Account")
		("AwsS3Storage.bucket", value(&awsbucket), "S3 Bucket AWS Account")
		("AwsS3Storage.region", value(&awsregion), "S3 Bucket region AWS Account")
		("AwsS3Storage.path", value(&awsBasePath), "S3 BasePath in Bucket AWS Account")
		("Logging.Console", value(&logging)->default_value(shouldLogToConsole), "true/false - Enable logs to console")
		("Logging.FileOutput", value(&logging), "filename - if exists emit logs to the file")
		("Logging.Verbosity", value(&logging_verbosity)->default_value(rootLogLevel), "Logging Verbosity - Default Info")
		("Repository.path", value(&repPath)->default_value(repositoryDB), "RepositoryDB path")
		("showOnly", "In restore show only the files to be restored")
		("BackupDB.path", value(&backupDBPath)->default_value(backupDB), "The name of the Backup database to use")
		;

	try
	{
		store(parse_command_line(argc, argv, desc), vm);
		std::string sbuConfigFileName;

		char* configFile = std::getenv(configFileEnvVar.c_str());
		if (configFile != NULL)
		{
			sbuConfigFileName = configFile;
		}

		if (!vm["config"].empty())
		{
			sbuConfigFileName = vm["config"].as<std::string>();
		}

		if (!sbuConfigFileName.empty())
		{
			if (boost::filesystem::exists(sbuConfigFileName))
			{
				auto fileParams = parse_config_file<char>(sbuConfigFileName.c_str(), desc, true);
				for (const auto& o : fileParams.options) {
					const std::string logComponentPrefix = "Logging.Components.";
					if (o.string_key.rfind(logComponentPrefix, 0) == 0)
					{
						LoggingComponentEntry entry;
						entry.componentName = o.string_key.substr(logComponentPrefix.size());
						entry.level = o.value[0];
						loggingOptions.components.push_back(entry);
					}

				}
				store(fileParams, vm);
			}
			else
			{
				return ExitCode_ConfigFileMissing;
			}
		}

		store(parse_environment(desc,
			[](const std::string& i_env_var)
			{// maps environment variable "HOSTNAME" to user-defined option "hostname"
				return i_env_var == "HOSTNAME" ? "hostname" : "";
			}),
			vm);

		if (!vm["help"].empty() || !vm["version"].empty())
		{
			std::cout << std::string("sbu ( Smart Backup Utility ) : ") + g_Version << std::endl;
			std::cout << std::string("Written by ") << std::string(g_DeveloperName) << std::endl;

			if (!vm["help"].empty())
			{
				std::cout << desc << std::endl;
				return ExitCode_HelpCalled;
			}
			else
			{
				return ExitCode_VersionCalled;
			}
		}

		if (vm["action"].empty())
		{
			std::cout << "Missing action argument" << std::endl;
			return ExitCode_MissingAction;
		}
	}
	catch (const boost::program_options::unknown_option exception)
	{
		std::cout << std::string("Invalid option ") << exception.get_option_name() << std::endl;
		retValue = ExitCode_InvalidArgument;
	}

	return retValue;
}
<|endoftext|>


<commit_before><commit_msg>Changes: Prevent ut_mtheme from hanging indefinitely in event loop.<commit_after><|endoftext|>


<commit_before>#include "unity/src/unity.h"
#include "unity/Helpers.h"
#include "stubs/database/DB_ReadWrite.h"
#include "database/Database.h"
#include "io/leds/LEDs.h"
#include "io/display/Config.h"
#include "board/Board.h"
#include "OpenDeck/sysconfig/SysConfig.h"

namespace
{
    class DBhandlers : public Database::Handlers
    {
        public:
        DBhandlers() {}

        void presetChange(uint8_t preset) override
        {
            if (presetChangeHandler != nullptr)
                presetChangeHandler(preset);
        }

        void factoryResetStart() override
        {
            if (factoryResetStartHandler != nullptr)
                factoryResetStartHandler();
        }

        void factoryResetDone() override
        {
            if (factoryResetDoneHandler != nullptr)
                factoryResetDoneHandler();
        }

        void initialized() override
        {
            if (initHandler != nullptr)
                initHandler();
        }

        //actions which these handlers should take depend on objects making
        //up the entire system to be initialized
        //therefore in interface we are calling these function pointers which
        // are set in application once we have all objects ready
        void (*presetChangeHandler)(uint8_t preset) = nullptr;
        void (*factoryResetStartHandler)()          = nullptr;
        void (*factoryResetDoneHandler)()           = nullptr;
        void (*initHandler)()                       = nullptr;
    } dbHandlers;

    DBstorageMock dbStorageMock;
    Database      database = Database(dbHandlers, dbStorageMock);
}    // namespace

TEST_SETUP()
{
    //init checks - no point in running further tests if these conditions fail
    TEST_ASSERT(database.init() == true);
    TEST_ASSERT(database.isSignatureValid() == true);
}

TEST_CASE(ReadInitialValues)
{
    //verify default values
    database.factoryReset(LESSDB::factoryResetType_t::full);

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);

        //MIDI block
        //feature section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(SysConfig::midiFeature_t::AMOUNT); i++)
            TEST_ASSERT(database.read(Database::Section::global_t::midiFeatures, i) == 0);

        //merge section
        //all values should be set to 0
        TEST_ASSERT(database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeType)) == 0);
        TEST_ASSERT(database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeUSBchannel)) == 0);
        TEST_ASSERT(database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeDINchannel)) == 0);

        //button block
        //type section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT(database.read(Database::Section::button_t::type, i) == 0);

        //midi message section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT(database.read(Database::Section::button_t::midiMessage, i) == 0);

        //midi id section
        //incremental values - first value should be 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT(database.read(Database::Section::button_t::midiID, i) == i);

        //midi velocity section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT(database.read(Database::Section::button_t::velocity, i) == 127);

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT(database.read(Database::Section::button_t::midiChannel, i) == 0);

        //encoders block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT(database.read(Database::Section::encoder_t::enable, i) == 0);

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT(database.read(Database::Section::encoder_t::invert, i) == 0);

        //mode section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT(database.read(Database::Section::encoder_t::mode, i) == 0);

        //midi id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT(database.read(Database::Section::encoder_t::midiID, i) == i);

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT(database.read(Database::Section::encoder_t::midiChannel, i) == 0);

        //pulses per step section
        //all values should be set to 4
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT(database.read(Database::Section::encoder_t::pulsesPerStep, i) == 4);

        //analog block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::enable, i) == 0);

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::invert, i) == 0);

        //type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::invert, i) == 0);

        //midi id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::midiID, i) == i);

        //lower limit section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::lowerLimit, i) == 0);

        //upper limit section
        //all values should be set to 16383
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::upperLimit, i) == 16383);

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT(database.read(Database::Section::analog_t::midiChannel, i) == 0);

        //LED block
        //global section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(IO::LEDs::setting_t::AMOUNT); i++)
            TEST_ASSERT(database.read(Database::Section::leds_t::global, i) == 0);

        //activation id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
            TEST_ASSERT(database.read(Database::Section::leds_t::activationID, i) == i);

        //rgb enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
            TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == 0);

        //control type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
            TEST_ASSERT(database.read(Database::Section::leds_t::controlType, i) == 0);

        //activation value section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
            TEST_ASSERT(database.read(Database::Section::leds_t::activationValue, i) == 127);

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
            TEST_ASSERT(database.read(Database::Section::leds_t::midiChannel, i) == 0);

#ifdef DISPLAY_SUPPORTED
        //display block
        //feature section
        TEST_ASSERT(database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::enable)) == 0);
        TEST_ASSERT(database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::welcomeMsg)) == 0);
        TEST_ASSERT(database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::vInfoMsg)) == 0);
        TEST_ASSERT(database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::MIDInotesAlternate)) == 0);

        //setting section
        TEST_ASSERT(database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::MIDIeventTime)) == 0);
        TEST_ASSERT(database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::octaveNormalization)) == 0);
#endif
    }
}

TEST_CASE(Presets)
{
    database.factoryReset(LESSDB::factoryResetType_t::full);

    //verify that first preset is active
    TEST_ASSERT(database.getPreset() == 0);

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);
        TEST_ASSERT(database.getPreset() == i);
    }

    if (database.getSupportedPresets() > 1)
    {
        //try setting value in preset 1, switch back to preset 0 and verify preset 0 still contains default value
        TEST_ASSERT(database.setPreset(1) == true);
        TEST_ASSERT(database.update(Database::Section::analog_t::midiID, 0, 127) == true);
        TEST_ASSERT(database.setPreset(0) == true);
        TEST_ASSERT(database.read(Database::Section::analog_t::midiID, 0) == 0);
    }

    //enable preset preservation, perform factory reset and verify that preservation is disabled
    database.setPresetPreserveState(true);
    TEST_ASSERT(database.getPresetPreserveState() == true);
    database.factoryReset(LESSDB::factoryResetType_t::full);
    database.init();
    TEST_ASSERT(database.getPresetPreserveState() == false);
}

TEST_CASE(FactoryReset)
{
    database.factoryReset(LESSDB::factoryResetType_t::full);

    //change several values
    TEST_ASSERT(database.update(Database::Section::button_t::midiID, 0, 114) == true);
    TEST_ASSERT(database.update(Database::Section::encoder_t::midiChannel, 0, 11) == true);

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::display_t::setting,
                                static_cast<size_t>(IO::Display::setting_t::controller),
                                static_cast<size_t>(U8X8::displayController_t::ssd1306)) == true);
#endif

    database.setPresetPreserveState(true);

    database.factoryReset(LESSDB::factoryResetType_t::full);

    //expect default values
    TEST_ASSERT(database.read(Database::Section::button_t::midiID, 0) == 0);
    TEST_ASSERT(database.read(Database::Section::encoder_t::midiChannel, 0) == 0);

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::display_t::setting,
                              static_cast<size_t>(IO::Display::setting_t::controller)) == static_cast<int32_t>(U8X8::displayController_t::invalid));
#endif

    TEST_ASSERT(database.getPresetPreserveState() == false);
}

#if MAX_NUMBER_OF_LEDS > 0
TEST_CASE(LEDs)
{
    //regression test
    //by default, rgb state should be disabled
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);

    TEST_ASSERT(database.update(Database::Section::leds_t::controlType, 0, static_cast<int32_t>(IO::LEDs::controlType_t::localPCforStateNoBlink)) == true);

    //rgb state shouldn't change
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);
}
#endif<commit_msg>tests: use TEST_ASSERT_EQUAL_UINT32 for database test<commit_after>#include "unity/src/unity.h"
#include "unity/Helpers.h"
#include "stubs/database/DB_ReadWrite.h"
#include "database/Database.h"
#include "io/leds/LEDs.h"
#include "io/display/Config.h"
#include "board/Board.h"
#include "OpenDeck/sysconfig/SysConfig.h"

namespace
{
    class DBhandlers : public Database::Handlers
    {
        public:
        DBhandlers() {}

        void presetChange(uint8_t preset) override
        {
            if (presetChangeHandler != nullptr)
                presetChangeHandler(preset);
        }

        void factoryResetStart() override
        {
            if (factoryResetStartHandler != nullptr)
                factoryResetStartHandler();
        }

        void factoryResetDone() override
        {
            if (factoryResetDoneHandler != nullptr)
                factoryResetDoneHandler();
        }

        void initialized() override
        {
            if (initHandler != nullptr)
                initHandler();
        }

        //actions which these handlers should take depend on objects making
        //up the entire system to be initialized
        //therefore in interface we are calling these function pointers which
        // are set in application once we have all objects ready
        void (*presetChangeHandler)(uint8_t preset) = nullptr;
        void (*factoryResetStartHandler)()          = nullptr;
        void (*factoryResetDoneHandler)()           = nullptr;
        void (*initHandler)()                       = nullptr;
    } dbHandlers;

    DBstorageMock dbStorageMock;
    Database      database = Database(dbHandlers, dbStorageMock);
}    // namespace

TEST_SETUP()
{
    //init checks - no point in running further tests if these conditions fail
    TEST_ASSERT(database.init() == true);
    TEST_ASSERT(database.isSignatureValid() == true);
}

TEST_CASE(ReadInitialValues)
{
    //verify default values
    database.factoryReset(LESSDB::factoryResetType_t::full);

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);

        //MIDI block
        //feature section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(SysConfig::midiFeature_t::AMOUNT); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiFeatures, i));

        //merge section
        //all values should be set to 0
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeType)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeUSBchannel)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeDINchannel)));

        //button block
        //type section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::type, i));

        //midi message section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::midiMessage, i));

        //midi id section
        //incremental values - first value should be 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, i));

        //midi velocity section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(127, database.read(Database::Section::button_t::velocity, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::midiChannel, i));

        //encoders block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::enable, i));

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::invert, i));

        //mode section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::mode, i));

        //midi id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::encoder_t::midiID, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::midiChannel, i));

        //pulses per step section
        //all values should be set to 4
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(4, database.read(Database::Section::encoder_t::pulsesPerStep, i));

        //analog block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::enable, i));

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::invert, i));

        //type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::invert, i));

        //midi id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::analog_t::midiID, i));

        //lower limit section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::lowerLimit, i));

        //upper limit section
        //all values should be set to 16383
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(16383, database.read(Database::Section::analog_t::upperLimit, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::midiChannel, i));

        //LED block
        //global section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(IO::LEDs::setting_t::AMOUNT); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::global, i));

        //activation id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::leds_t::activationID, i));

        //rgb enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS + (MAX_TOUCHSCREEN_BUTTONS / 3); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::rgbEnable, i));

        //control type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::controlType, i));

        //activation value section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(127, database.read(Database::Section::leds_t::activationValue, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::midiChannel, i));

#ifdef DISPLAY_SUPPORTED
        //display block
        //feature section
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::enable)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::welcomeMsg)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::vInfoMsg)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::MIDInotesAlternate)));

        //setting section
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::MIDIeventTime)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::octaveNormalization)));
#endif
    }
}

TEST_CASE(Presets)
{
    database.factoryReset(LESSDB::factoryResetType_t::full);

    //verify that first preset is active
    TEST_ASSERT(database.getPreset() == 0);

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);
        TEST_ASSERT(database.getPreset() == i);
    }

    if (database.getSupportedPresets() > 1)
    {
        //try setting value in preset 1, switch back to preset 0 and verify preset 0 still contains default value
        TEST_ASSERT(database.setPreset(1) == true);
        TEST_ASSERT(database.update(Database::Section::analog_t::midiID, 0, 127) == true);
        TEST_ASSERT(database.setPreset(0) == true);
        TEST_ASSERT(database.read(Database::Section::analog_t::midiID, 0) == 0);
    }

    //enable preset preservation, perform factory reset and verify that preservation is disabled
    database.setPresetPreserveState(true);
    TEST_ASSERT(database.getPresetPreserveState() == true);
    database.factoryReset(LESSDB::factoryResetType_t::full);
    database.init();
    TEST_ASSERT(database.getPresetPreserveState() == false);
}

TEST_CASE(FactoryReset)
{
    database.factoryReset(LESSDB::factoryResetType_t::full);

    //change several values
    TEST_ASSERT(database.update(Database::Section::button_t::midiID, 0, 114) == true);
    TEST_ASSERT(database.update(Database::Section::encoder_t::midiChannel, 0, 11) == true);

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::display_t::setting,
                                static_cast<size_t>(IO::Display::setting_t::controller),
                                static_cast<size_t>(U8X8::displayController_t::ssd1306)) == true);
#endif

    database.setPresetPreserveState(true);

    database.factoryReset(LESSDB::factoryResetType_t::full);

    //expect default values
    TEST_ASSERT(database.read(Database::Section::button_t::midiID, 0) == 0);
    TEST_ASSERT(database.read(Database::Section::encoder_t::midiChannel, 0) == 0);

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::display_t::setting,
                              static_cast<size_t>(IO::Display::setting_t::controller)) == static_cast<int32_t>(U8X8::displayController_t::invalid));
#endif

    TEST_ASSERT(database.getPresetPreserveState() == false);
}

#if MAX_NUMBER_OF_LEDS > 0
TEST_CASE(LEDs)
{
    //regression test
    //by default, rgb state should be disabled
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);

    TEST_ASSERT(database.update(Database::Section::leds_t::controlType, 0, static_cast<int32_t>(IO::LEDs::controlType_t::localPCforStateNoBlink)) == true);

    //rgb state shouldn't change
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);
}
#endif<|endoftext|>


<commit_before>#include "unity/src/unity.h"
#include "unity/Helpers.h"
#include "stubs/database/DB_ReadWrite.h"
#include "database/Database.h"
#include "io/leds/LEDs.h"
#include "io/display/Config.h"
#include "OpenDeck/sysconfig/SysConfig.h"

namespace
{
    class DBhandlers : public Database::Handlers
    {
        public:
        DBhandlers() {}

        void presetChange(uint8_t preset) override
        {
            if (presetChangeHandler != nullptr)
                presetChangeHandler(preset);
        }

        void factoryResetStart() override
        {
            if (factoryResetStartHandler != nullptr)
                factoryResetStartHandler();
        }

        void factoryResetDone() override
        {
            if (factoryResetDoneHandler != nullptr)
                factoryResetDoneHandler();
        }

        void initialized() override
        {
            if (initHandler != nullptr)
                initHandler();
        }

        //actions which these handlers should take depend on objects making
        //up the entire system to be initialized
        //therefore in interface we are calling these function pointers which
        // are set in application once we have all objects ready
        void (*presetChangeHandler)(uint8_t preset) = nullptr;
        void (*factoryResetStartHandler)()          = nullptr;
        void (*factoryResetDoneHandler)()           = nullptr;
        void (*initHandler)()                       = nullptr;
    } dbHandlers;

    DBstorageMock dbStorageMock;
    Database      database = Database(dbHandlers, dbStorageMock, true);
}    // namespace

TEST_SETUP()
{
    //init checks - no point in running further tests if these conditions fail
    TEST_ASSERT(database.init() == true);
    TEST_ASSERT(database.isSignatureValid() == true);
}

TEST_CASE(ReadInitialValues)
{
    //verify default values
    database.factoryReset();

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);

        //MIDI block
        //feature section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(SysConfig::midiFeature_t::AMOUNT); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiFeatures, i));

        //merge section
        //all values should be set to 0
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeType)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeUSBchannel)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeDINchannel)));

        //button block
        //type section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::type, i));

        //midi message section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::midiMessage, i));

        //midi id section
        //incremental values - first value should be 0, each successive value should be incremented by 1 for each group
        //(physical/analog/touchscreen)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, i));

        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, MAX_NUMBER_OF_BUTTONS + i));

        for (int i = 0; i < MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + i));

        //midi velocity section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(127, database.read(Database::Section::button_t::velocity, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::midiChannel, i));

        //encoders block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::enable, i));

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::invert, i));

        //mode section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::mode, i));

        //midi id section
        //incremental values - first value should be set to MAX_NUMBER_OF_ANALOG, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(MAX_NUMBER_OF_ANALOG + i, database.read(Database::Section::encoder_t::midiID, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::midiChannel, i));

        //pulses per step section
        //all values should be set to 4
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(4, database.read(Database::Section::encoder_t::pulsesPerStep, i));

        //analog block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::enable, i));

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::invert, i));

        //type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::invert, i));

        //midi id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::analog_t::midiID, i));

        //lower limit section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::lowerLimit, i));

        //upper limit section
        //all values should be set to 16383
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(16383, database.read(Database::Section::analog_t::upperLimit, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::midiChannel, i));

        //LED block
        //global section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(IO::LEDs::setting_t::AMOUNT); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::global, i));

        //activation id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1 for each group
        //(physical/touchscreen)
        for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::leds_t::activationID, i));

        for (int i = 0; i < MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::leds_t::activationID, MAX_NUMBER_OF_LEDS + i));

        //rgb enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS + (MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS / 3); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::rgbEnable, i));

        //control type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::controlType, i));

        //activation value section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(127, database.read(Database::Section::leds_t::activationValue, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::midiChannel, i));

#ifdef DISPLAY_SUPPORTED
        //display block
        //feature section
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::enable)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::welcomeMsg)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::vInfoMsg)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::MIDInotesAlternate)));

        //setting section
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::MIDIeventTime)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::octaveNormalization)));
#endif
    }
}

TEST_CASE(Presets)
{
    database.factoryReset();

    //verify that first preset is active
    TEST_ASSERT(database.getPreset() == 0);

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);
        TEST_ASSERT(database.getPreset() == i);
    }

    if (database.getSupportedPresets() > 1)
    {
        //try setting value in preset 1, switch back to preset 0 and verify preset 0 still contains default value
        TEST_ASSERT(database.setPreset(1) == true);
        TEST_ASSERT(database.update(Database::Section::analog_t::midiID, 0, 127) == true);
        TEST_ASSERT(database.setPreset(0) == true);
        TEST_ASSERT(database.read(Database::Section::analog_t::midiID, 0) == 0);
    }

    //enable preset preservation, perform factory reset and verify that preservation is disabled
    database.setPresetPreserveState(true);
    TEST_ASSERT(database.getPresetPreserveState() == true);
    database.factoryReset();
    database.init();
    TEST_ASSERT(database.getPresetPreserveState() == false);
}

TEST_CASE(FactoryReset)
{
    database.factoryReset();

    //change several values
#ifdef BUTTONS_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::button_t::midiID, 0, 114) == true);
#endif

#ifdef ENCODERS_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::encoder_t::midiChannel, 0, 11) == true);
#endif

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::display_t::setting,
                                static_cast<size_t>(IO::Display::setting_t::controller),
                                static_cast<size_t>(IO::U8X8::displayController_t::ssd1306)) == true);
#endif

    database.setPresetPreserveState(true);

    database.factoryReset();

    //expect default values
#ifdef BUTTONS_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::button_t::midiID, 0) == 0);
#endif

#ifdef ENCODERS_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::encoder_t::midiChannel, 0) == 0);
#endif

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::display_t::setting,
                              static_cast<size_t>(IO::Display::setting_t::controller)) == static_cast<int32_t>(IO::U8X8::displayController_t::invalid));
#endif

    TEST_ASSERT(database.getPresetPreserveState() == false);
}

#if MAX_NUMBER_OF_LEDS > 0
TEST_CASE(LEDs)
{
    //regression test
    //by default, rgb state should be disabled
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);

    TEST_ASSERT(database.update(Database::Section::leds_t::controlType, 0, static_cast<int32_t>(IO::LEDs::controlType_t::localPCforStateNoBlink)) == true);

    //rgb state shouldn't change
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);
}
#endif<commit_msg>tests: add missing db factory reset in db test, remove explicit sig check<commit_after>#include "unity/src/unity.h"
#include "unity/Helpers.h"
#include "stubs/database/DB_ReadWrite.h"
#include "database/Database.h"
#include "io/leds/LEDs.h"
#include "io/display/Config.h"
#include "OpenDeck/sysconfig/SysConfig.h"

namespace
{
    class DBhandlers : public Database::Handlers
    {
        public:
        DBhandlers() {}

        void presetChange(uint8_t preset) override
        {
            if (presetChangeHandler != nullptr)
                presetChangeHandler(preset);
        }

        void factoryResetStart() override
        {
            if (factoryResetStartHandler != nullptr)
                factoryResetStartHandler();
        }

        void factoryResetDone() override
        {
            if (factoryResetDoneHandler != nullptr)
                factoryResetDoneHandler();
        }

        void initialized() override
        {
            if (initHandler != nullptr)
                initHandler();
        }

        //actions which these handlers should take depend on objects making
        //up the entire system to be initialized
        //therefore in interface we are calling these function pointers which
        // are set in application once we have all objects ready
        void (*presetChangeHandler)(uint8_t preset) = nullptr;
        void (*factoryResetStartHandler)()          = nullptr;
        void (*factoryResetDoneHandler)()           = nullptr;
        void (*initHandler)()                       = nullptr;
    } dbHandlers;

    DBstorageMock dbStorageMock;
    Database      database = Database(dbHandlers, dbStorageMock, true);
}    // namespace

TEST_SETUP()
{
    //init checks - no point in running further tests if these conditions fail
    TEST_ASSERT(database.init() == true);
}

TEST_CASE(ReadInitialValues)
{
    //verify default values
    database.factoryReset();

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);

        //MIDI block
        //feature section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(SysConfig::midiFeature_t::AMOUNT); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiFeatures, i));

        //merge section
        //all values should be set to 0
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeType)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeUSBchannel)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::global_t::midiMerge, static_cast<size_t>(SysConfig::midiMerge_t::mergeDINchannel)));

        //button block
        //type section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::type, i));

        //midi message section
        //all values should be set to 0 (default type)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::midiMessage, i));

        //midi id section
        //incremental values - first value should be 0, each successive value should be incremented by 1 for each group
        //(physical/analog/touchscreen)
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, i));

        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, MAX_NUMBER_OF_BUTTONS + i));

        for (int i = 0; i < MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::button_t::midiID, MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + i));

        //midi velocity section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(127, database.read(Database::Section::button_t::velocity, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_BUTTONS + MAX_NUMBER_OF_ANALOG + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::button_t::midiChannel, i));

        //encoders block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::enable, i));

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::invert, i));

        //mode section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::mode, i));

        //midi id section
        //incremental values - first value should be set to MAX_NUMBER_OF_ANALOG, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(MAX_NUMBER_OF_ANALOG + i, database.read(Database::Section::encoder_t::midiID, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::encoder_t::midiChannel, i));

        //pulses per step section
        //all values should be set to 4
        for (int i = 0; i < MAX_NUMBER_OF_ENCODERS; i++)
            TEST_ASSERT_EQUAL_UINT32(4, database.read(Database::Section::encoder_t::pulsesPerStep, i));

        //analog block
        //enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::enable, i));

        //invert section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::invert, i));

        //type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::invert, i));

        //midi id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::analog_t::midiID, i));

        //lower limit section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::lowerLimit, i));

        //upper limit section
        //all values should be set to 16383
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(16383, database.read(Database::Section::analog_t::upperLimit, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_ANALOG; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::analog_t::midiChannel, i));

        //LED block
        //global section
        //all values should be set to 0
        for (int i = 0; i < static_cast<uint8_t>(IO::LEDs::setting_t::AMOUNT); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::global, i));

        //activation id section
        //incremental values - first value should be set to 0, each successive value should be incremented by 1 for each group
        //(physical/touchscreen)
        for (int i = 0; i < MAX_NUMBER_OF_LEDS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::leds_t::activationID, i));

        for (int i = 0; i < MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(i, database.read(Database::Section::leds_t::activationID, MAX_NUMBER_OF_LEDS + i));

        //rgb enable section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS + (MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS / 3); i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::rgbEnable, i));

        //control type section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::controlType, i));

        //activation value section
        //all values should be set to 127
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(127, database.read(Database::Section::leds_t::activationValue, i));

        //midi channel section
        //all values should be set to 0
        for (int i = 0; i < MAX_NUMBER_OF_LEDS + MAX_NUMBER_OF_TOUCHSCREEN_BUTTONS; i++)
            TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::leds_t::midiChannel, i));

#ifdef DISPLAY_SUPPORTED
        //display block
        //feature section
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::enable)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::welcomeMsg)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::vInfoMsg)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::features, static_cast<size_t>(IO::Display::feature_t::MIDInotesAlternate)));

        //setting section
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::MIDIeventTime)));
        TEST_ASSERT_EQUAL_UINT32(0, database.read(Database::Section::display_t::setting, static_cast<size_t>(IO::Display::setting_t::octaveNormalization)));
#endif
    }
}

TEST_CASE(Presets)
{
    database.factoryReset();

    //verify that first preset is active
    TEST_ASSERT(database.getPreset() == 0);

    for (int i = 0; i < database.getSupportedPresets(); i++)
    {
        TEST_ASSERT(database.setPreset(i) == true);
        TEST_ASSERT(database.getPreset() == i);
    }

    if (database.getSupportedPresets() > 1)
    {
        //try setting value in preset 1, switch back to preset 0 and verify preset 0 still contains default value
        TEST_ASSERT(database.setPreset(1) == true);
        TEST_ASSERT(database.update(Database::Section::analog_t::midiID, 0, 127) == true);
        TEST_ASSERT(database.setPreset(0) == true);
        TEST_ASSERT(database.read(Database::Section::analog_t::midiID, 0) == 0);
    }

    //enable preset preservation, perform factory reset and verify that preservation is disabled
    database.setPresetPreserveState(true);
    TEST_ASSERT(database.getPresetPreserveState() == true);
    database.factoryReset();
    database.init();
    TEST_ASSERT(database.getPresetPreserveState() == false);
}

TEST_CASE(FactoryReset)
{
    database.factoryReset();

    //change several values
#ifdef BUTTONS_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::button_t::midiID, 0, 114) == true);
#endif

#ifdef ENCODERS_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::encoder_t::midiChannel, 0, 11) == true);
#endif

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.update(Database::Section::display_t::setting,
                                static_cast<size_t>(IO::Display::setting_t::controller),
                                static_cast<size_t>(IO::U8X8::displayController_t::ssd1306)) == true);
#endif

    database.setPresetPreserveState(true);

    database.factoryReset();

    //expect default values
#ifdef BUTTONS_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::button_t::midiID, 0) == 0);
#endif

#ifdef ENCODERS_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::encoder_t::midiChannel, 0) == 0);
#endif

#ifdef DISPLAY_SUPPORTED
    TEST_ASSERT(database.read(Database::Section::display_t::setting,
                              static_cast<size_t>(IO::Display::setting_t::controller)) == static_cast<int32_t>(IO::U8X8::displayController_t::invalid));
#endif

    TEST_ASSERT(database.getPresetPreserveState() == false);
}

#if MAX_NUMBER_OF_LEDS > 0
TEST_CASE(LEDs)
{
    database.factoryReset();

    //regression test
    //by default, rgb state should be disabled
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);

    TEST_ASSERT(database.update(Database::Section::leds_t::controlType, 0, static_cast<int32_t>(IO::LEDs::controlType_t::localPCforStateNoBlink)) == true);

    //rgb state shouldn't change
    for (int i = 0; i < MAX_NUMBER_OF_RGB_LEDS; i++)
        TEST_ASSERT(database.read(Database::Section::leds_t::rgbEnable, i) == false);
}
#endif<|endoftext|>


<commit_before>#ifndef DUNE_FUNCTIONALS_DISCRETEFUNCTIONSPACE_FINITEELEMENT_HH
#define DUNE_FUNCTIONALS_DISCRETEFUNCTIONSPACE_FINITEELEMENT_HH

// dune-fem includes
#include <dune/fem/space/lagrangespace.hh>

// dune-functionals includes
#include <dune/functionals/common/localbasefunctionprovider.hh>

namespace Dune
{

namespace Functionals
{

namespace DiscreteFunctionSpace
{

template< class FunctionSpaceImp, class GridPartImp, int polOrder >
class ContinuousFiniteElement
{
public:

  typedef FunctionSpaceImp
    FunctionSpaceType;

  typedef GridPartImp
    GridPartType;

  typedef Dune::LagrangeDiscreteFunctionSpace< FunctionSpaceType, GridPartType, polOrder >
    HostSpaceType;

  typedef typename HostSpaceType::RangeFieldType
    RangeFieldType;

  typedef typename HostSpaceType::EntityType
    EntityType;

  typedef Dune::Functionals::Common::LocalBaseFunctionProvider< HostSpaceType >
    LocalBaseFunctionProviderType;

  ContinuousFiniteElement( GridPartType& gridPart )
    : gridPart_( gridPart ),
      hostSpace_( gridPart ),
      localBaseFunctionProvider_( hostSpace_ )
  {
  }

  const GridPartType& gridPart() const
  {
    return gridPart_;
  }

  const HostSpaceType& hostSpace() const
  {
    return hostSpace_;
  }

  const LocalBaseFunctionProviderType& localBaseFunctionProvider() const
  {
    return localBaseFunctionProvider_;
  }

private:

  const GridPartType& gridPart_;
  const HostSpaceType hostSpace_;
  const LocalBaseFunctionProviderType localBaseFunctionProvider_;

}; // end class ContinuousFiniteElement

} // end namespace DiscreteFunctionSpace

} // end namespace Functionals

} // end namespace Dune

#endif // DUNE_FUNCTIONALS_DISCRETEFUNCTIONSPACE_FINITEELEMENT_HH
<commit_msg>added LocalBasefucntion to DiscreteFunctionSPace::ContinuousFiniteElement<commit_after>#ifndef DUNE_FUNCTIONALS_DISCRETEFUNCTIONSPACE_FINITEELEMENT_HH
#define DUNE_FUNCTIONALS_DISCRETEFUNCTIONSPACE_FINITEELEMENT_HH

// dune-fem includes
#include <dune/fem/space/lagrangespace.hh>

//dune-functionals includes
#include <dune/functionals/common/localbasefunction.hh>

namespace Dune
{

namespace Functionals
{

namespace DiscreteFunctionSpace
{

template< class FunctionSpaceImp, class GridPartImp, int polOrder >
class ContinuousFiniteElement
{
public:

  typedef FunctionSpaceImp
    FunctionSpaceType;

  typedef GridPartImp
    GridPartType;

  typedef Dune::LagrangeDiscreteFunctionSpace< FunctionSpaceType, GridPartType, polOrder >
    HostSpaceType;

  typedef Dune::Functionals::Common::LocalBaseFunction< HostSpaceType >
    LocalBaseFunctionType;

  typedef typename HostSpaceType::EntityType
    EntityType;

  ContinuousFiniteElement( GridPartType& gridPart )
    : gridPart_( gridPart ),
      hostSpace_( gridPart )
  {
  }

  const GridPartType& gridPart() const
  {
    return gridPart_;
  }

  const HostSpaceType& hostSpace() const
  {
    return hostSpace_;
  }

  const LocalBaseFunctionType localBaseFunction( const EntityType& entity, const unsigned int localDoFNumber ) const
  {
    return LocalBaseFunctionType( entity, hostSpace_.baseFunctionSet( entity ), localDoFNumber );
  }

private:

  const GridPartType& gridPart_;
  const HostSpaceType hostSpace_;

}; // end class ContinuousFiniteElement

} // end namespace DiscreteFunctionSpace

} // end namespace Functionals

} // end namespace Dune

#endif // DUNE_FUNCTIONALS_DISCRETEFUNCTIONSPACE_FINITEELEMENT_HH
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <sstream>
#include <typeinfo>
#include <time.h>
#define SEQAN_DEBUG
#define SEQAN_TEST

#include <seqan/sequence.h>
#include <seqan/score.h>

using namespace std;
using namespace seqan;

#define TEST_PATH "projects/tests/score/"
#define LIB_PATH "projects/library/seqan/score/"

//////////////////////////////////////////////////////////////////////////////

template <typename TScore1, typename TScore2>
void testCompareAAMatrices(TScore1 & mat1,
						   TScore2 & mat2)
{
	AminoAcid a, b;
	for (a = 'A'; a <= '*'; ++a)
	{
		for (b = 'A'; b <= '*'; ++b)
		{
			SEQAN_TASSERT(score(mat1, a, b) == score(mat2, a, b))
		}
	}
}

void testMatrixScore()
{
	Score<int, ScoreMatrix<> > sc;
	String<char> meta;
	loadScoreMatrix(sc, TEST_PATH "BLOSUM62", meta);

//	write(cout, Blosum62()); //does it work with a temporary?

	//compare the matrix loaded from file with the build-in matrix
	Blosum62 blosum62;
	testCompareAAMatrices(blosum62, sc);

	//store and load again
	FILE * fl = fopen(TEST_PATH "testfile.txt", "wb");
	write(fl, sc, meta);
	fclose(fl);

	Score<int, ScoreMatrix<> > sc2;
	String<char> meta2;
	loadScoreMatrix(sc2, TEST_PATH "testfile.txt", meta2);
	testCompareAAMatrices(sc, sc2);
	SEQAN_TASSERT(meta == meta2)

	//store and load again build-in matrix
	fl = fopen(TEST_PATH "testfile.txt", "wb");
	write(fl, Blosum62());
	fclose(fl);

	loadScoreMatrix(sc2, TEST_PATH "testfile.txt");
	testCompareAAMatrices(sc, Blosum62());

	//test setScore()
	setScore(sc, 'A', '*', 100);
	SEQAN_TASSERT(score(sc, 'A', '*') == 100)
}

//////////////////////////////////////////////////////////////////////////////
//compare to http://www.bioinformatics.nl/tools/pam.html

void testScorePAM()
{
//	PamJones pam;

	PamDayhoff pam;
	//Score<int, Pam<> > pam(250, -1, 0);
	//Score<int, Pam<AminoAcid, Pam_Data_Dayhoff_MDM78> > pam;

	SEQAN_TASSERT(getDist(pam) == 250);
	SEQAN_TASSERT(scoreGapExtend(pam) == -1);
	SEQAN_TASSERT(scoreGapOpen(pam) == 0);

	//store and load again build-in matrix
	FILE * fl = fopen(TEST_PATH "testfile.txt", "wb");
	write(fl, pam);
	fclose(fl);

	Score<int, ScoreMatrix<> > sc;
	loadScoreMatrix(sc, TEST_PATH "testfile.txt");
	testCompareAAMatrices(sc, PamDayhoff());
}

//////////////////////////////////////////////////////////////////////////////

int main()
{
	SEQAN_TREPORT("TEST BEGIN")

	testScorePAM();

	testMatrixScore();

//____________________________________________________________________________

	SEQAN_TREPORT("TEST END")

	return 0;
}
<commit_msg><commit_after>#include <iostream>
#include <fstream>
#include <sstream>
#include <typeinfo>
#include <time.h>
#define SEQAN_DEBUG
#define SEQAN_TEST

#include <seqan/sequence.h>
#include <seqan/score.h>

using namespace std;
using namespace seqan;

#define TEST_PATH "projects/tests/score/"
#define LIB_PATH "projects/library/seqan/score/"

//////////////////////////////////////////////////////////////////////////////

template <typename TScore1, typename TScore2>
void testCompareAAMatrices(TScore1 const & mat1,
						   TScore2 const & mat2)
{
	AminoAcid a, b;
	for (a = 'A'; a <= '*'; ++a)
	{
		for (b = 'A'; b <= '*'; ++b)
		{
			SEQAN_TASSERT(score(mat1, a, b) == score(mat2, a, b))
		}
	}
}

void testMatrixScore()
{
	Score<int, ScoreMatrix<> > sc;
	String<char> meta;
	loadScoreMatrix(sc, TEST_PATH "BLOSUM62", meta);

	//compare the matrix loaded from file with the build-in matrix
	Blosum62 blosum62;
	testCompareAAMatrices(blosum62, sc);

	//store and load again
	FILE * fl = fopen(TEST_PATH "testfile.txt", "wb");
	write(fl, sc, meta);
	fclose(fl);

	Score<int, ScoreMatrix<> > sc2;
	String<char> meta2;
	loadScoreMatrix(sc2, TEST_PATH "testfile.txt", meta2);
	testCompareAAMatrices(sc, sc2);
	SEQAN_TASSERT(meta == meta2)

	//store and load again build-in matrix
	fl = fopen(TEST_PATH "testfile.txt", "wb");
	write(fl, Blosum62());
	fclose(fl);

	loadScoreMatrix(sc2, TEST_PATH "testfile.txt");
	testCompareAAMatrices(sc, Blosum62());

	//test setScore()
	setScore(sc, 'A', '*', 100);
	SEQAN_TASSERT(score(sc, 'A', '*') == 100)
}

//////////////////////////////////////////////////////////////////////////////
//compare to http://www.bioinformatics.nl/tools/pam.html

void testScorePAM()
{
//	PamJones pam;

	PamDayhoff pam;
	//Score<int, Pam<> > pam(250, -1, 0);
	//Score<int, Pam<AminoAcid, Pam_Data_Dayhoff_MDM78> > pam;

	SEQAN_TASSERT(getDist(pam) == 250);
	SEQAN_TASSERT(scoreGapExtend(pam) == -1);
	SEQAN_TASSERT(scoreGapOpen(pam) == 0);

	//store and load again build-in matrix
	FILE * fl = fopen(TEST_PATH "testfile.txt", "wb");
	write(fl, pam);
	fclose(fl);

	Score<int, ScoreMatrix<> > sc;
	loadScoreMatrix(sc, TEST_PATH "testfile.txt");
	testCompareAAMatrices(sc, PamDayhoff());
}

//////////////////////////////////////////////////////////////////////////////

int main()
{
	SEQAN_TREPORT("TEST BEGIN")

	testScorePAM();

	testMatrixScore();

//____________________________________________________________________________

	SEQAN_TREPORT("TEST END")

	return 0;
}
<|endoftext|>


<commit_before>/**
 * elf_parser.cpp - Implementation of ELF binary perser
 * @author Alexander Titov <alexander.igorevich.titov@gmail.com>
 * Copyright 2013 MIPT-MIPS iLab project
 */

// Genereic C
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <cassert>

// Generic C++
#include <iostream>
#include <sstream>
#include <memory>

// Unix
#include <unistd.h>
#include <fcntl.h>

// LibELF
#include <libelf.h>

// uArchSim modules
#include <infra/macro.h>
#include "elf_parser.h"

ElfSection::ElfSection( const ElfSection& that)
    : name( that.name), size( that.size), start_addr( that.start_addr), content( new uint8[size])
{
    std::memcpy(this->content, that.content, this->size);
}

ElfSection::ElfSection( const char* name, Addr start_addr,
                        Addr size, const uint8* content_that)
    : name( name), size( size)
    , start_addr( start_addr), content( new uint8[ size + sizeof( uint64)])
{
    std::memcpy( this->content, content_that, size);
}

void ElfSection::getAllElfSections( const char* elf_file_name,
                                    std::list<ElfSection>& sections_array /*is used as output*/)
{
    // open the binary file, we have to use C-style open,
    // because it is required by elf_begin function
    int file_descr = open( elf_file_name, O_RDONLY|O_BINARY);
    if ( file_descr < 0)
    {
        std::cerr << "ERROR: Could not open file " << elf_file_name << ": "
                  << std::strerror( errno) << std::endl;
        std::exit( EXIT_FAILURE);
    }

    // set ELF library operating version
    if ( elf_version( EV_CURRENT) == EV_NONE)
    {
        std::cerr << "ERROR: Could not set ELF library operating version:"
                  <<  elf_errmsg( elf_errno()) << std::endl;
        std::exit( EXIT_FAILURE);
    }

    // open the file in ELF format
    Elf* elf = elf_begin( file_descr, ELF_C_READ, nullptr);
    if ( elf == nullptr)
    {
        std::cerr << "ERROR: Could not open file " << elf_file_name
                  << " as ELF file: "
                  <<  elf_errmsg( elf_errno()) << std::endl;
        std::exit( EXIT_FAILURE);
    }

    size_t shstrndx;
    elf_getshdrstrndx( elf, &shstrndx);

    Elf_Scn *section = nullptr;
    while ( (section = elf_nextscn( elf, section)) != nullptr)
    {
        Elf32_Shdr shdr = *elf32_getshdr( section);

        char* name = elf_strptr( elf, shstrndx, shdr.sh_name);
        Addr start_addr = shdr.sh_addr;

        if ( start_addr == 0)
            continue;

        size_t size = shdr.sh_size;
        auto offset = shdr.sh_offset;
        std::unique_ptr<uint8[]> content(new uint8[ size]);

        lseek( file_descr, offset, SEEK_SET);
        FILE *file = fdopen( file_descr, "r");
        if ( file == nullptr)
        {
            std::cerr << "ERROR: Could not open file " << elf_file_name << ": "
                 << std::strerror(errno) << std::endl;
            std::exit( EXIT_FAILURE);
        }

        // fill the content by the section data
        ignored( std::fread( content.get(), sizeof( uint8), size, file));
        sections_array.emplace( sections_array.end(), name, start_addr, size, content.get());
    }

    // close all used files
    elf_end( elf);
    close( file_descr);
}

ElfSection::~ElfSection()
{
    delete [] this->content;
}

std::string ElfSection::dump( std::string indent) const
{
    std::ostringstream oss;

    oss << indent << "Dump ELF section \"" << this->name << "\"" << std::endl
        << indent << "  size = " << this->size << " Bytes" << std::endl
        << indent << "  start_addr = 0x"
        << std::hex << this->start_addr << std::dec << std::endl
        << indent << "  Content:" << std::endl;

    std::string str = this->strByBytes();

    // split the contents into words of 4 bytes
    bool skip_was_printed = false;
    for ( size_t offset = 0; offset < this->size; offset += sizeof( uint32))
    {
        std::string substr =  str.substr( 2 * offset, // 2 hex digits is need per byte
                                     sizeof( uint64));

        if ( substr.compare( "00000000") == 0)
        {
            if ( !skip_was_printed)
            {
                oss << indent << "  ....  " << std::endl;
                skip_was_printed = true;
            }
        }
        else
        {
            oss << indent << "    0x"
                << std::hex << ( this->start_addr + offset)
                << indent << ":    " << substr << std::endl;
            skip_was_printed = false;
        }
    }

    return oss.str();
}

std::string ElfSection::strByBytes() const
{
    // temp stream is used to convert numbers into the output string
    std::ostringstream oss;
    oss << std::hex;

    // convert each byte into 2 hex digits
    for( size_t i = 0; i < this->size; ++i)
    {
        oss.width( 2); // because we need two hex symbols to print a byte (e.g. "ff")
        oss.fill( '0'); // thus, number 8 will be printed as "08"
        uint16 value = *( this->content + i); // need converting to uint16
                                              // to be not preinted as an alphabet symbol

        // print a value of
        oss << value;
    }

    return oss.str();
}

std::string ElfSection::strByWords() const
{
    // temp stream is used to convert numbers into the output string
    std::ostringstream oss;
    oss << std::hex;

    // convert each words of 4 bytes into 8 hex digits
    for( size_t i = 0; i < this->size/sizeof( uint32); ++i)
    {
        oss.width( 8); // because we need 8 hex symbols to print a word (e.g. "ffffffff")
        oss.fill( '0'); // thus, number a44f will be printed as "0000a44f"

        oss << *( reinterpret_cast<uint32*>(this->content) + i); // NOLINT
    }

    return oss.str();
}

<commit_msg>Define O_BINARY for Linux<commit_after>/**
 * elf_parser.cpp - Implementation of ELF binary perser
 * @author Alexander Titov <alexander.igorevich.titov@gmail.com>
 * Copyright 2013 MIPT-MIPS iLab project
 */

// Genereic C
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cerrno>
#include <cassert>

// Generic C++
#include <iostream>
#include <sstream>
#include <memory>

// Unix
#include <unistd.h>
#include <fcntl.h>

// LibELF
#include <libelf.h>

// uArchSim modules
#include <infra/macro.h>
#include "elf_parser.h"

#ifndef O_BINARY
#define O_BINARY 0
#endif

ElfSection::ElfSection( const ElfSection& that)
    : name( that.name), size( that.size), start_addr( that.start_addr), content( new uint8[size])
{
    std::memcpy(this->content, that.content, this->size);
}

ElfSection::ElfSection( const char* name, Addr start_addr,
                        Addr size, const uint8* content_that)
    : name( name), size( size)
    , start_addr( start_addr), content( new uint8[ size + sizeof( uint64)])
{
    std::memcpy( this->content, content_that, size);
}

void ElfSection::getAllElfSections( const char* elf_file_name,
                                    std::list<ElfSection>& sections_array /*is used as output*/)
{
    // open the binary file, we have to use C-style open,
    // because it is required by elf_begin function
    int file_descr = open( elf_file_name, O_RDONLY|O_BINARY);
    if ( file_descr < 0)
    {
        std::cerr << "ERROR: Could not open file " << elf_file_name << ": "
                  << std::strerror( errno) << std::endl;
        std::exit( EXIT_FAILURE);
    }

    // set ELF library operating version
    if ( elf_version( EV_CURRENT) == EV_NONE)
    {
        std::cerr << "ERROR: Could not set ELF library operating version:"
                  <<  elf_errmsg( elf_errno()) << std::endl;
        std::exit( EXIT_FAILURE);
    }

    // open the file in ELF format
    Elf* elf = elf_begin( file_descr, ELF_C_READ, nullptr);
    if ( elf == nullptr)
    {
        std::cerr << "ERROR: Could not open file " << elf_file_name
                  << " as ELF file: "
                  <<  elf_errmsg( elf_errno()) << std::endl;
        std::exit( EXIT_FAILURE);
    }

    size_t shstrndx;
    elf_getshdrstrndx( elf, &shstrndx);

    Elf_Scn *section = nullptr;
    while ( (section = elf_nextscn( elf, section)) != nullptr)
    {
        Elf32_Shdr shdr = *elf32_getshdr( section);

        char* name = elf_strptr( elf, shstrndx, shdr.sh_name);
        Addr start_addr = shdr.sh_addr;

        if ( start_addr == 0)
            continue;

        size_t size = shdr.sh_size;
        auto offset = shdr.sh_offset;
        std::unique_ptr<uint8[]> content(new uint8[ size]);

        lseek( file_descr, offset, SEEK_SET);
        FILE *file = fdopen( file_descr, "r");
        if ( file == nullptr)
        {
            std::cerr << "ERROR: Could not open file " << elf_file_name << ": "
                 << std::strerror(errno) << std::endl;
            std::exit( EXIT_FAILURE);
        }

        // fill the content by the section data
        ignored( std::fread( content.get(), sizeof( uint8), size, file));
        sections_array.emplace( sections_array.end(), name, start_addr, size, content.get());
    }

    // close all used files
    elf_end( elf);
    close( file_descr);
}

ElfSection::~ElfSection()
{
    delete [] this->content;
}

std::string ElfSection::dump( std::string indent) const
{
    std::ostringstream oss;

    oss << indent << "Dump ELF section \"" << this->name << "\"" << std::endl
        << indent << "  size = " << this->size << " Bytes" << std::endl
        << indent << "  start_addr = 0x"
        << std::hex << this->start_addr << std::dec << std::endl
        << indent << "  Content:" << std::endl;

    std::string str = this->strByBytes();

    // split the contents into words of 4 bytes
    bool skip_was_printed = false;
    for ( size_t offset = 0; offset < this->size; offset += sizeof( uint32))
    {
        std::string substr =  str.substr( 2 * offset, // 2 hex digits is need per byte
                                     sizeof( uint64));

        if ( substr.compare( "00000000") == 0)
        {
            if ( !skip_was_printed)
            {
                oss << indent << "  ....  " << std::endl;
                skip_was_printed = true;
            }
        }
        else
        {
            oss << indent << "    0x"
                << std::hex << ( this->start_addr + offset)
                << indent << ":    " << substr << std::endl;
            skip_was_printed = false;
        }
    }

    return oss.str();
}

std::string ElfSection::strByBytes() const
{
    // temp stream is used to convert numbers into the output string
    std::ostringstream oss;
    oss << std::hex;

    // convert each byte into 2 hex digits
    for( size_t i = 0; i < this->size; ++i)
    {
        oss.width( 2); // because we need two hex symbols to print a byte (e.g. "ff")
        oss.fill( '0'); // thus, number 8 will be printed as "08"
        uint16 value = *( this->content + i); // need converting to uint16
                                              // to be not preinted as an alphabet symbol

        // print a value of
        oss << value;
    }

    return oss.str();
}

std::string ElfSection::strByWords() const
{
    // temp stream is used to convert numbers into the output string
    std::ostringstream oss;
    oss << std::hex;

    // convert each words of 4 bytes into 8 hex digits
    for( size_t i = 0; i < this->size/sizeof( uint32); ++i)
    {
        oss.width( 8); // because we need 8 hex symbols to print a word (e.g. "ffffffff")
        oss.fill( '0'); // thus, number a44f will be printed as "0000a44f"

        oss << *( reinterpret_cast<uint32*>(this->content) + i); // NOLINT
    }

    return oss.str();
}

<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// constant_translator.cpp
//
// Identification: src/codegen/expression/constant_translator.cpp
//
// Copyright (c) 2015-2017, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "codegen/expression/constant_translator.h"

#include "codegen/type/sql_type.h"
#include "expression/constant_value_expression.h"
#include "type/value_peeker.h"

namespace peloton {
namespace codegen {

// Constructor
ConstantTranslator::ConstantTranslator(
    const expression::ConstantValueExpression &exp, CompilationContext &ctx)
    : ExpressionTranslator(exp, ctx) {}

// Return an LLVM value for our constant (i.e., a compile-time constant)
codegen::Value ConstantTranslator::DeriveValue(
    CodeGen &codegen, UNUSED_ATTRIBUTE RowBatch::Row &row) const {
  // Pull out the constant from the expression
  const peloton::type::Value &constant =
      GetExpressionAs<expression::ConstantValueExpression>().GetValue();

  // Convert the value into an LLVM compile-time constant
  llvm::Value *val = nullptr;
  llvm::Value *len = nullptr;
  switch (constant.GetTypeId()) {
    case peloton::type::TypeId::TINYINT: {
      val = codegen.Const8(peloton::type::ValuePeeker::PeekTinyInt(constant));
      break;
    }
    case peloton::type::TypeId::SMALLINT: {
      val = codegen.Const16(peloton::type::ValuePeeker::PeekSmallInt(constant));
      break;
    }
    case peloton::type::TypeId::INTEGER: {
      val = codegen.Const32(peloton::type::ValuePeeker::PeekInteger(constant));
      break;
    }
    case peloton::type::TypeId::BIGINT: {
      val = codegen.Const64(peloton::type::ValuePeeker::PeekBigInt(constant));
      break;
    }
    case peloton::type::TypeId::DECIMAL: {
      val =
          codegen.ConstDouble(peloton::type::ValuePeeker::PeekDouble(constant));
      break;
    }
    case peloton::type::TypeId::DATE: {
      val = codegen.Const32(peloton::type::ValuePeeker::PeekDate(constant));
      break;
    }
    case peloton::type::TypeId::TIMESTAMP: {
      val =
          codegen.Const64(peloton::type::ValuePeeker::PeekTimestamp(constant));
      break;
    }
    case peloton::type::TypeId::VARCHAR: {
      std::string str = peloton::type::ValuePeeker::PeekVarchar(constant);
      // val should be a pointer type to be used in comparisions inside a PHI
      val = codegen.ConstStringPtr(str);
      len = codegen.Const32(str.length() + 1); // length includes the null-terminator
      break;
    }
    default: {
      throw Exception{"Unknown constant value type " +
                      TypeIdToString(constant.GetTypeId())};
    }
  }
  return codegen::Value{type::SqlType::LookupType(constant.GetTypeId()), val,
                        len, nullptr};
}

}  // namespace codegen
}  // namespace peloton
<commit_msg>Small changes<commit_after>//===----------------------------------------------------------------------===//
//
//                         Peloton
//
// constant_translator.cpp
//
// Identification: src/codegen/expression/constant_translator.cpp
//
// Copyright (c) 2015-2017, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include "codegen/expression/constant_translator.h"

#include "codegen/type/sql_type.h"
#include "expression/constant_value_expression.h"
#include "type/value_peeker.h"

namespace peloton {
namespace codegen {

// Constructor
ConstantTranslator::ConstantTranslator(
    const expression::ConstantValueExpression &exp, CompilationContext &ctx)
    : ExpressionTranslator(exp, ctx) {}

codegen::Value ConstantTranslator::DeriveValue(
    CodeGen &codegen, UNUSED_ATTRIBUTE RowBatch::Row &row) const {
  // Pull out the constant from the expression
  const peloton::type::Value &constant =
      GetExpressionAs<expression::ConstantValueExpression>().GetValue();

  // Convert the constant into a codegen::Value
  llvm::Value *val = nullptr;
  llvm::Value *len = nullptr;
  switch (constant.GetTypeId()) {
    case peloton::type::TypeId::TINYINT: {
      val = codegen.Const8(peloton::type::ValuePeeker::PeekTinyInt(constant));
      break;
    }
    case peloton::type::TypeId::SMALLINT: {
      val = codegen.Const16(peloton::type::ValuePeeker::PeekSmallInt(constant));
      break;
    }
    case peloton::type::TypeId::INTEGER: {
      val = codegen.Const32(peloton::type::ValuePeeker::PeekInteger(constant));
      break;
    }
    case peloton::type::TypeId::BIGINT: {
      val = codegen.Const64(peloton::type::ValuePeeker::PeekBigInt(constant));
      break;
    }
    case peloton::type::TypeId::DECIMAL: {
      val =
          codegen.ConstDouble(peloton::type::ValuePeeker::PeekDouble(constant));
      break;
    }
    case peloton::type::TypeId::DATE: {
      val = codegen.Const32(peloton::type::ValuePeeker::PeekDate(constant));
      break;
    }
    case peloton::type::TypeId::TIMESTAMP: {
      val =
          codegen.Const64(peloton::type::ValuePeeker::PeekTimestamp(constant));
      break;
    }
    case peloton::type::TypeId::VARCHAR: {
      std::string str = peloton::type::ValuePeeker::PeekVarchar(constant);
      val = codegen.ConstStringPtr(str);
      len = codegen.Const32(str.length() + 1); // length includes the null-terminator
      break;
    }
    default: {
      throw Exception{"Unknown constant value type " +
                      TypeIdToString(constant.GetTypeId())};
    }
  }
  return codegen::Value{type::SqlType::LookupType(constant.GetTypeId()), val,
                        len, nullptr};
}

}  // namespace codegen
}  // namespace peloton
<|endoftext|>


<commit_before>#include "File.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#endif

#ifdef ANDROID
#include <android/asset_manager.h>
AAssetManager* File::s_assetManager = nullptr;
#endif

File::File(const char* path)
{
#ifdef _WIN32
	m_file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
	if(m_file != INVALID_HANDLE_VALUE)
	{
		LARGE_INTEGER size;
		GetFileSizeEx(m_file, &size);
		m_size = size.QuadPart;
		m_fileMapping = CreateFileMapping(m_file, nullptr, PAGE_READONLY, (DWORD)(m_size >> 32), (DWORD)m_size, nullptr);
		m_data = MapViewOfFile(m_fileMapping, FILE_MAP_READ, 0, 0, m_size);
	}
	else
	{
		m_fileMapping = INVALID_HANDLE_VALUE;
		m_size = 0;
		m_data = nullptr;
	}
#else
#ifdef ANDROID
	if(strncmp(path, "assets/", 7) == 0)
	{
		path += 7;
	}
	m_asset = AAssetManager_open(s_assetManager, path, AASSET_MODE_BUFFER);
	m_data = AAsset_getBuffer(m_asset);
	m_size = (size_t)AAsset_getLength(m_asset);
#else
	m_file = open(path, O_RDONLY);
	if(m_file != -1)
	{
		struct stat buf;
		fstat(m_file, &buf);
		m_size = buf.st_size;
		m_data = mmap(nullptr, m_size, PROT_READ, MAP_PRIVATE, m_file, 0);
	}
	else
	{
		m_size = 0;
		m_data = nullptr;
	}
#endif
#endif
}

File::~File()
{
#ifdef _WIN32
	if(m_data)
	{
		UnmapViewOfFile(m_data);
	}

	if(m_fileMapping != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_fileMapping);
	}

	if(m_file != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_file);
	}
#else
#ifdef ANDROID
	AAsset_close(m_asset);
#else
	if(m_data)
	{
		munmap(const_cast<void*>(m_data), m_size);
	}

	if(m_file != -1)
	{
		close(m_file);
	}
#endif
#endif
}

size_t File::getSize() const
{
	return m_size;
}

const void* File::getData() const
{
	return m_data;
}

#ifdef ANDROID
void File::init(AAssetManager* assetManager)
{
	s_assetManager = assetManager;
}
#endif
<commit_msg>Fixed a warning.<commit_after>#include "File.h"

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <Windows.h>
#else
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#endif

#ifdef ANDROID
#include <android/asset_manager.h>
AAssetManager* File::s_assetManager = nullptr;
#endif

File::File(const char* path)
{
#ifdef _WIN32
	m_file = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
	if(m_file != INVALID_HANDLE_VALUE)
	{
		LARGE_INTEGER size;
		GetFileSizeEx(m_file, &size);
		m_size = size.QuadPart;
		m_fileMapping = CreateFileMapping(m_file, nullptr, PAGE_READONLY, (DWORD)(m_size >> 32), (DWORD)m_size, nullptr);
		m_data = MapViewOfFile(m_fileMapping, FILE_MAP_READ, 0, 0, m_size);
	}
	else
	{
		m_fileMapping = INVALID_HANDLE_VALUE;
		m_size = 0;
		m_data = nullptr;
	}
#else
#ifdef ANDROID
	if(strncmp(path, "assets/", 7) == 0)
	{
		path += 7;
	}
	m_asset = AAssetManager_open(s_assetManager, path, AASSET_MODE_BUFFER);
	m_data = AAsset_getBuffer(m_asset);
	m_size = (size_t)AAsset_getLength(m_asset);
#else
	m_file = open(path, O_RDONLY);
	if(m_file != -1)
	{
		struct stat buf;
		fstat(m_file, &buf);
		m_size = (size_t)buf.st_size;
		m_data = mmap(nullptr, m_size, PROT_READ, MAP_PRIVATE, m_file, 0);
	}
	else
	{
		m_size = 0;
		m_data = nullptr;
	}
#endif
#endif
}

File::~File()
{
#ifdef _WIN32
	if(m_data)
	{
		UnmapViewOfFile(m_data);
	}

	if(m_fileMapping != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_fileMapping);
	}

	if(m_file != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_file);
	}
#else
#ifdef ANDROID
	AAsset_close(m_asset);
#else
	if(m_data)
	{
		munmap(const_cast<void*>(m_data), m_size);
	}

	if(m_file != -1)
	{
		close(m_file);
	}
#endif
#endif
}

size_t File::getSize() const
{
	return m_size;
}

const void* File::getData() const
{
	return m_data;
}

#ifdef ANDROID
void File::init(AAssetManager* assetManager)
{
	s_assetManager = assetManager;
}
#endif
<|endoftext|>


<commit_before><commit_msg>Fix normal map sample<commit_after><|endoftext|>