<commit_before>/*
  The MIT License (MIT)
  Copyright (c) 2016 Xu Cheng
  See licensing at:
    https://opensource.org/licenses/MIT
*/

#pragma once

#include <exception>
#include <string>
#include "pbc-streamopen.hpp"

namespace pbc
{
    namespace backend
    {
#include <pbc/pbc.h>
    };

    class NotAllocatedException : public std::runtime_error
    {
    public:
        NotAllocatedException() : runtime_error("Object is not allocated.") {}
    };

    class AlreadyAllocatedException : public std::runtime_error
    {
    public:
        AlreadyAllocatedException()
            : runtime_error("Object is already allocated.")
        {
        }
    };

    class InitializationError : public std::runtime_error
    {
    public:
        InitializationError() : runtime_error("Failed to initialize object.") {}
        InitializationError(const std::string& msg) : runtime_error(msg) {}
    };

    class Pairing;
    class PairingParam;
    class Element;
    typedef std::shared_ptr<Pairing> PairingPtr;
    typedef std::shared_ptr<PairingParam> PairingParamPtr;
    typedef std::shared_ptr<Element> ElementPtr;

    class PairingParam
    {
    public:
        PairingParam() = default;
        PairingParam(const PairingParam&) = delete;
        ~PairingParam() { backend::pbc_param_clear(_param); }
        std::string to_str()
        {
            std::stringstream buf;
            backend::stream_fd_ptr sfd = backend::streamopen(buf);
            backend::pbc_param_out_str(sfd->fd, _param);
            backend::streamclose(sfd);
            return buf.str();
        }

        static PairingParamPtr init_from_str(const std::string& param_str)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            if (backend::pbc_param_init_set_str(ptr->_param,
                                                param_str.c_str()) != 0)
                throw InitializationError(
                    "Failed to initialize pairing parameter.");
            return ptr;
        }
        static PairingParamPtr gen_type_a(int rbits = 160, int qbits = 512)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_a_gen(ptr->_param, rbits, qbits);
            return ptr;
        }
        static PairingParamPtr gen_type_i(int group_size = 696)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_i_gen(ptr->_param, group_size);
            return ptr;
        }
        static PairingParamPtr gen_type_e(int rbits = 160, int qbits = 1024)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_e_gen(ptr->_param, rbits, qbits);
            return ptr;
        }
        static PairingParamPtr gen_type_f(int bits = 160)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_f_gen(ptr->_param, bits);
            return ptr;
        }

    private:
        friend class Pairing;
        backend::pbc_param_t _param;
    };

    class Pairing
    {
    public:
        Pairing() = default;
        Pairing(const Pairing&) = delete;
        ~Pairing() { pairing_clear(_pairing); }
        static PairingPtr init_from_param_str(const std::string& param_str)
        {
            return Pairing::init_from_param(
                PairingParam::init_from_str(param_str));
            PairingPtr ptr = std::make_shared<Pairing>();
            if (backend::pairing_init_set_str(ptr->_pairing,
                                              param_str.c_str()) != 0)
                throw InitializationError("Failed to initialize pairing.");
            return ptr;
        }
        static PairingPtr init_from_param(const PairingParamPtr& param)
        {
            PairingPtr ptr = std::make_shared<Pairing>();
            backend::pairing_init_pbc_param(ptr->_pairing, param->_param);
            return ptr;
        }

        bool symmetric() { return backend::pairing_is_symmetric(_pairing); }
        int g1_bytes_length()
        {
            return backend::pairing_length_in_bytes_G1(_pairing);
        }
        int g1_x_only_bytes_length()
        {
            return backend::pairing_length_in_bytes_x_only_G1(_pairing);
        }
        int g1_compressed_bytes_length()
        {
            return backend::pairing_length_in_bytes_compressed_G1(_pairing);
        }
        int g2_bytes_length()
        {
            return backend::pairing_length_in_bytes_G2(_pairing);
        }
        int g2_x_only_bytes_length()
        {
            return backend::pairing_length_in_bytes_x_only_G2(_pairing);
        }
        int g2_compressed_bytes_length()
        {
            return backend::pairing_length_in_bytes_compressed_G2(_pairing);
        }
        int gt_bytes_length()
        {
            return backend::pairing_length_in_bytes_GT(_pairing);
        }
        int zr_bytes_length()
        {
            return backend::pairing_length_in_bytes_Zr(_pairing);
        }

    private:
        backend::pairing_t _pairing;
    };

    class Element
    {
    public:
        Element() : _allocated(false), _size(0) {}
        Element(const Element& e) : _allocated(e._allocated), _size(e._size)
        {
            if (_allocated) {
                backend::element_init_same_as(
                    _element, *(backend::element_t*)&e._element);
                backend::element_set(_element,
                                     *(backend::element_t*)&e._element);
            }
        }
        Element(Element&& e) noexcept : _allocated(e._allocated), _size(e._size)
        {
            std::memcpy(&_element[0], &e._element[0],
                        sizeof(backend::element_t));
            e._allocated = false;
            e._size = 0;
        }
        ~Element()
        {
            if (_allocated) {
                backend::element_clear(_element);
                _allocated = false;
                _size = 0;
            }
        }

    private:
        bool _allocated;
        std::size_t _size;
        backend::element_t _element;
    };
};
<commit_msg>change exception name<commit_after>/*
  The MIT License (MIT)
  Copyright (c) 2016 Xu Cheng
  See licensing at:
    https://opensource.org/licenses/MIT
*/

#pragma once

#include <exception>
#include <string>
#include "pbc-streamopen.hpp"

namespace pbc
{
    namespace backend
    {
#include <pbc/pbc.h>
    };

    class NotInitializedError: public std::runtime_error
    {
    public:
        NotInitializedError() : runtime_error("Object is not initialized.") {}
    };

    class AlreadyInitializedError: public std::runtime_error
    {
    public:
        AlreadyInitializedError()
            : runtime_error("Object is already initialized.")
        {
        }
    };

    class InitializationError : public std::runtime_error
    {
    public:
        InitializationError() : runtime_error("Failed to initialize object.") {}
        InitializationError(const std::string& msg) : runtime_error(msg) {}
    };

    class Pairing;
    class PairingParam;
    class Element;
    typedef std::shared_ptr<Pairing> PairingPtr;
    typedef std::shared_ptr<PairingParam> PairingParamPtr;
    typedef std::shared_ptr<Element> ElementPtr;

    class PairingParam
    {
    public:
        PairingParam() = default;
        PairingParam(const PairingParam&) = delete;
        ~PairingParam() { backend::pbc_param_clear(_param); }
        std::string to_str()
        {
            std::stringstream buf;
            backend::stream_fd_ptr sfd = backend::streamopen(buf);
            backend::pbc_param_out_str(sfd->fd, _param);
            backend::streamclose(sfd);
            return buf.str();
        }

        static PairingParamPtr init_from_str(const std::string& param_str)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            if (backend::pbc_param_init_set_str(ptr->_param,
                                                param_str.c_str()) != 0)
                throw InitializationError(
                    "Failed to initialize pairing parameter.");
            return ptr;
        }
        static PairingParamPtr gen_type_a(int rbits = 160, int qbits = 512)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_a_gen(ptr->_param, rbits, qbits);
            return ptr;
        }
        static PairingParamPtr gen_type_i(int group_size = 696)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_i_gen(ptr->_param, group_size);
            return ptr;
        }
        static PairingParamPtr gen_type_e(int rbits = 160, int qbits = 1024)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_e_gen(ptr->_param, rbits, qbits);
            return ptr;
        }
        static PairingParamPtr gen_type_f(int bits = 160)
        {
            PairingParamPtr ptr = std::make_shared<PairingParam>();
            backend::pbc_param_init_f_gen(ptr->_param, bits);
            return ptr;
        }

    private:
        friend class Pairing;
        backend::pbc_param_t _param;
    };

    class Pairing
    {
    public:
        Pairing() = default;
        Pairing(const Pairing&) = delete;
        ~Pairing() { pairing_clear(_pairing); }
        static PairingPtr init_from_param_str(const std::string& param_str)
        {
            return Pairing::init_from_param(
                PairingParam::init_from_str(param_str));
            PairingPtr ptr = std::make_shared<Pairing>();
            if (backend::pairing_init_set_str(ptr->_pairing,
                                              param_str.c_str()) != 0)
                throw InitializationError("Failed to initialize pairing.");
            return ptr;
        }
        static PairingPtr init_from_param(const PairingParamPtr& param)
        {
            PairingPtr ptr = std::make_shared<Pairing>();
            backend::pairing_init_pbc_param(ptr->_pairing, param->_param);
            return ptr;
        }

        bool symmetric() { return backend::pairing_is_symmetric(_pairing); }
        int g1_bytes_length()
        {
            return backend::pairing_length_in_bytes_G1(_pairing);
        }
        int g1_x_only_bytes_length()
        {
            return backend::pairing_length_in_bytes_x_only_G1(_pairing);
        }
        int g1_compressed_bytes_length()
        {
            return backend::pairing_length_in_bytes_compressed_G1(_pairing);
        }
        int g2_bytes_length()
        {
            return backend::pairing_length_in_bytes_G2(_pairing);
        }
        int g2_x_only_bytes_length()
        {
            return backend::pairing_length_in_bytes_x_only_G2(_pairing);
        }
        int g2_compressed_bytes_length()
        {
            return backend::pairing_length_in_bytes_compressed_G2(_pairing);
        }
        int gt_bytes_length()
        {
            return backend::pairing_length_in_bytes_GT(_pairing);
        }
        int zr_bytes_length()
        {
            return backend::pairing_length_in_bytes_Zr(_pairing);
        }

    private:
        backend::pairing_t _pairing;
    };

    class Element
    {
    public:
        Element() : _allocated(false), _size(0) {}
        Element(const Element& e) : _allocated(e._allocated), _size(e._size)
        {
            if (_allocated) {
                backend::element_init_same_as(
                    _element, *(backend::element_t*)&e._element);
                backend::element_set(_element,
                                     *(backend::element_t*)&e._element);
            }
        }
        Element(Element&& e) noexcept : _allocated(e._allocated), _size(e._size)
        {
            std::memcpy(&_element[0], &e._element[0],
                        sizeof(backend::element_t));
            e._allocated = false;
            e._size = 0;
        }
        ~Element()
        {
            if (_allocated) {
                backend::element_clear(_element);
                _allocated = false;
                _size = 0;
            }
        }

    private:
        bool _allocated;
        std::size_t _size;
        backend::element_t _element;
    };
};
<|endoftext|>


<commit_before>// 01.01.2017 Султан Xottab_DUTY Урамаев
// Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.
#include <iostream>
#include <thread>

#include <GLFW/glfw3.h>
#include "dynlib/Dynlib.hpp"

#include "Common/Platform.hpp"
#include "xdCore/Log.hpp"
#include "xdCore/xdCore.hpp"
#include "ConsoleCommand.hpp"
#include "ConsoleCommands.hpp"
#include "xdEngine.hpp"

void InitializeConsole()
{
    ConsoleCommands = new XDay::CC_Container;
    Console = new XDay::xdConsole;
    Console->Initialize();
}

void destroyConsole()
{
    ConsoleCommands->Execute(&ConfigSaveCC);
    ConsoleCommands->Execute(&FlushLogCC);
    ConsoleCommands->Destroy();
    delete ConsoleCommands;
    delete Console;
}

void HelpCmdArgs()
{
    Info("\nAvailable parameters:\n"\
        "--p_name - Specifies AppName, default is \"X-Day Engine\" \n"\
        "--p_game - Specifies game module to be attached, default is \"xdGame\";\n"\
        "--p_datapath - Specifies path of application data folder, default is \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Specifies path of resources folder, default is \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Specifies path and name of main config file (path/name.extension), default is \"*DataPath*/main.config\" \n"\
        "--p_nolog - Completely disables engine log. May increase performance\n"\
        "--p_nologflush - Disables log flushing. Useless if -nolog defined\n"\
        "--p_debug - Enables debug mode\n"
        "--p_syscmd - Disables system console hiding\n"
        "--p_shrec - Compile shaders even if they already compiled\n"\
        "--p_shpre - Outputs preprocessed shaders to the shader sources dir. Works only in debug mode\n"\
        "--p_texture - Specifies path to texture file to load, default is \"texture.dds\"\n"\
        "--p_model - Specifies path to model file to model, default is \"model.dds\"\n");

    Info("\nДоступные параметры:\n"\
        "--p_name - Задаёт AppName, по умолчанию: \"X-Day Engine\" \n"\
        "--p_game - Задаёт игровую библиотеку для подключения, по умолчанию: \"xdGame\";\n"
        "--p_datapath - Задаёт путь до папки с настройками, по умолчанию: \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Задаёт путь до папки с ресурсами, по умолчанию: \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Задаёт путь и имя главного файла настроек (путь/имя.расширение), по умолчанию: \"*DataPath*/main.config\" \n"\
        "--p_nolog - Полностью выключает лог движка. Может повысить производительность\n"\
        "--p_nologflush - Выключает сброс лога в файл. Не имеет смысла если задан -nolog\n"\
        "--p_debug - Включает режим отладки\n"
        "--p_syscmd - Отключает скрытие системной консоли\n"
        "--p_shrec - Сборка шейдеров даже если они уже собраны\n"\
        "--p_shpre - Сохраняет обработанные шейдеры в папку исходников шейдеров. Работает только в режиме отладки\n"\
        "--p_texture - Задаёт путь до текстуры для загрузки, по умолчанию: \"texture.dds\"\n"\
        "--p_model - Задаёт путь до модели для загрузки, по умолчанию: \"model.dds\"\n");
}

void threadedConsole()
{
    while (!glfwWindowShouldClose(Engine.windowMain))
    {
        std::string input;
        std::getline(std::cin, input);
        if (Console && ConsoleCommands && !glfwWindowShouldClose(Engine.windowMain))
            ConsoleCommands->Execute(input);
        else
            break;
    }
}

void AttachRenderer()
{
    const auto handle = Dynlib::open(Core.GetModuleName(XDay::eRendererModule).c_str());

    const auto func = (FunctionPointer)Dynlib::load(handle, "InitializeRenderer");
    if (func)
        func();
    else
        Error("Cannot attach function InitializeRenderer from {}", Core.GetModuleName(XDay::eRendererModule));
}

int main(int argc, char* argv[])
{
    system("chcp 65001");

    Core.InitializeArguments(argc, argv);

#ifdef WINDOWS
    if (!Core.FindParam(XDay::eParamDontHideSystemConsole))
        FreeConsole();
#endif

    Core.Initialize();
    InitializeConsole();

    DebugMsg(Core.GetGLFWVersionString());
    Info(Core.GetBuildString());
    Info("Core.Params: " + Core.ParamsString);
    Info("Девиз: Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.");
    Info("Slogan: It's more interesting to shoot your feet, than catch arrows by your knee. Let's continue.");
    HelpCmdArgs();

    ConsoleCommands->ExecuteConfig(Console->ConfigFile);
    ErrorIf(!glfwInit(), "GLFW not initialized.");

    AttachRenderer();

    Engine.Initialize();
    Engine.createMainWindow();

    std::thread WatchConsole(threadedConsole);
    if (Core.FindParam(XDay::eParamDontHideSystemConsole))
        WatchConsole.detach();

    Engine.InitRender();

    Engine.mainLoop();

    WatchConsole.~thread();

    glfwTerminate();

    destroyConsole();

    return 0;
}
<commit_msg>Optimize console usage of DontHideSystemConsole Core param<commit_after>// 01.01.2017 Султан Xottab_DUTY Урамаев
// Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.
#include <iostream>
#include <thread>

#include <GLFW/glfw3.h>
#include "dynlib/Dynlib.hpp"

#include "Common/Platform.hpp"
#include "xdCore/Log.hpp"
#include "xdCore/xdCore.hpp"
#include "ConsoleCommand.hpp"
#include "ConsoleCommands.hpp"
#include "xdEngine.hpp"

void InitializeConsole()
{
    ConsoleCommands = new XDay::CC_Container;
    Console = new XDay::xdConsole;
    Console->Initialize();
}

void destroyConsole()
{
    ConsoleCommands->Execute(&ConfigSaveCC);
    ConsoleCommands->Execute(&FlushLogCC);
    ConsoleCommands->Destroy();
    delete ConsoleCommands;
    delete Console;
}

void HelpCmdArgs()
{
    Info("\nAvailable parameters:\n"\
        "--p_name - Specifies AppName, default is \"X-Day Engine\" \n"\
        "--p_game - Specifies game module to be attached, default is \"xdGame\";\n"\
        "--p_datapath - Specifies path of application data folder, default is \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Specifies path of resources folder, default is \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Specifies path and name of main config file (path/name.extension), default is \"*DataPath*/main.config\" \n"\
        "--p_nolog - Completely disables engine log. May increase performance\n"\
        "--p_nologflush - Disables log flushing. Useless if -nolog defined\n"\
        "--p_debug - Enables debug mode\n"
        "--p_syscmd - Disables system console hiding\n"
        "--p_shrec - Compile shaders even if they already compiled\n"\
        "--p_shpre - Outputs preprocessed shaders to the shader sources dir. Works only in debug mode\n"\
        "--p_texture - Specifies path to texture file to load, default is \"texture.dds\"\n"\
        "--p_model - Specifies path to model file to model, default is \"model.dds\"\n");

    Info("\nДоступные параметры:\n"\
        "--p_name - Задаёт AppName, по умолчанию: \"X-Day Engine\" \n"\
        "--p_game - Задаёт игровую библиотеку для подключения, по умолчанию: \"xdGame\";\n"
        "--p_datapath - Задаёт путь до папки с настройками, по умолчанию: \"*WorkingDirectory*/appdata\"\n"\
        "--p_respath - Задаёт путь до папки с ресурсами, по умолчанию: \"*WorkingDirectory*/resources\"\n"\
        "--p_mainconfig - Задаёт путь и имя главного файла настроек (путь/имя.расширение), по умолчанию: \"*DataPath*/main.config\" \n"\
        "--p_nolog - Полностью выключает лог движка. Может повысить производительность\n"\
        "--p_nologflush - Выключает сброс лога в файл. Не имеет смысла если задан -nolog\n"\
        "--p_debug - Включает режим отладки\n"
        "--p_syscmd - Отключает скрытие системной консоли\n"
        "--p_shrec - Сборка шейдеров даже если они уже собраны\n"\
        "--p_shpre - Сохраняет обработанные шейдеры в папку исходников шейдеров. Работает только в режиме отладки\n"\
        "--p_texture - Задаёт путь до текстуры для загрузки, по умолчанию: \"texture.dds\"\n"\
        "--p_model - Задаёт путь до модели для загрузки, по умолчанию: \"model.dds\"\n");
}

void watch_console()
{
#ifdef DEBUG
    const bool allowed = true;
#else
    const bool allowed = Core.FindParam(XDay::eParamDontHideSystemConsole);
#endif

    while (allowed && !glfwWindowShouldClose(Engine.windowMain))
    {
        std::string input;
        std::getline(std::cin, input);
        if (Console && ConsoleCommands && !glfwWindowShouldClose(Engine.windowMain))
            ConsoleCommands->Execute(input);
        else
            break;
    }
}

void AttachRenderer()
{
    const auto handle = Dynlib::open(Core.GetModuleName(XDay::eRendererModule).c_str());

    const auto func = (FunctionPointer)Dynlib::load(handle, "InitializeRenderer");
    if (func)
        func();
    else
        Error("Cannot attach function InitializeRenderer from {}", Core.GetModuleName(XDay::eRendererModule));
}

int main(int argc, char* argv[])
{
    system("chcp 65001");

    Core.InitializeArguments(argc, argv);

#ifdef WINDOWS
    if (!Core.FindParam(XDay::eParamDontHideSystemConsole))
        FreeConsole();
#endif

    Core.Initialize();
    InitializeConsole();

    DebugMsg(Core.GetGLFWVersionString());
    Info(Core.GetBuildString());
    Info("Core.Params: " + Core.ParamsString);
    Info("Девиз: Чем стрелы коленом ловить, гораздо интереснее отстреливать свои ноги. Продолжим.");
    Info("Slogan: It's more interesting to shoot your feet, than catch arrows by your knee. Let's continue.");
    HelpCmdArgs();

    ConsoleCommands->ExecuteConfig(Console->ConfigFile);
    ErrorIf(!glfwInit(), "GLFW not initialized.");

    AttachRenderer();

    Engine.Initialize();
    Engine.createMainWindow();

    std::thread WatchConsole(watch_console);

    Engine.InitRender();

    Engine.mainLoop();

    WatchConsole.~thread();

    glfwTerminate();

    destroyConsole();

    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) Wiesław Šoltés. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include "StdAfx.h"
#include "MainApp.h"
#include "XmlConfig.h"

namespace xml
{
    CString CXmlConfig::GetRootName(CString szFileXml, XmlDocumnent &doc)
    {
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            const char *name = XmlDoc::GetRootName(doc);
            if (name != nullptr)
                return CString(name);
        }
        return CString();
    }

    bool CXmlConfig::LoadOptions(XmlDocumnent &doc, config::COptions &options)
    {
        XmlOptions xml(doc);
        return xml.GetOptions(options);
    }

    bool CXmlConfig::LoadOptions(CString szFileXml, config::COptions &options)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadOptions(doc, options);
        }
        return false;
    }

    bool CXmlConfig::SaveOptions(CString szFileXml, config::COptions &options)
    {
        XmlDocumnent doc;
        XmlOptions xml(doc);
        xml.Create();
        xml.SetOptions(options);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadItem(XmlDocumnent &doc, config::CItem &item)
    {
        XmlItems xml(doc);
        return xml.GetItem(item);
    }

    bool CXmlConfig::LoadItem(CString szFileXml, config::CItem &item)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadItem(doc, item);
        }
        return false;
    }

    bool CXmlConfig::SaveItem(CString szFileXml, config::CItem &item)
    {
        XmlDocumnent doc;
        XmlItems xml(doc);
        xml.Create();
        xml.SetItem(item);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadItems(XmlDocumnent &doc, config::CItemsList &items)
    {
        XmlItems xml(doc);
        return xml.GetItems(items);
    }

    bool CXmlConfig::LoadItems(CString szFileXml, config::CItemsList &items)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadItems(doc, items);
        }
        return false;
    }

    bool CXmlConfig::SaveItems(CString szFileXml, config::CItemsList &items)
    {
        XmlDocumnent doc;
        XmlItems xml(doc);
        xml.Create();
        xml.SetItems(items);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadLanguage(XmlDocumnent &doc, lang::CLanguage &language)
    {
        XmlLanguages xml(doc);
        return xml.GetLanguage(language);
    }

    bool CXmlConfig::LoadLanguage(CString szFileXml, lang::CLanguage &language)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadLanguage(doc, language);
        }
        return false;
    }

    bool CXmlConfig::SaveLanguage(CString szFileXml, lang::CLanguage &language)
    {
        XmlDocumnent doc;
        XmlLanguages xml(doc);
        xml.Create();
        xml.SetLanguage(language);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadLanguages(XmlDocumnent &doc, lang::CLanguagesList &languages)
    {
        XmlLanguages xml(doc);
        return xml.GetLanguages(languages);
    }

    bool CXmlConfig::LoadLanguages(CString szFileXml, lang::CLanguagesList &languages)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadLanguages(doc, languages);
        }
        return false;
    }

    bool CXmlConfig::SaveLanguages(CString szFileXml, lang::CLanguagesList &languages)
    {
        XmlDocumnent doc;
        XmlLanguages xml(doc);
        xml.Create();
        xml.SetLanguages(languages);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadPreset(XmlDocumnent &doc, config::CPreset &preset)
    {
        XmlPresets xml(doc);
        return xml.GetPreset(preset);
    }

    bool CXmlConfig::LoadPreset(CString szFileXml, config::CPreset &preset)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadPreset(doc, preset);
        }
        return false;
    }

    bool CXmlConfig::SavePreset(CString szFileXml, config::CPreset &preset)
    {
        XmlDocumnent doc;
        XmlPresets xml(doc);
        xml.Create();
        xml.SetPreset(preset);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadPresets(XmlDocumnent &doc, config::CPresetsList &presets)
    {
        XmlPresets xml(doc);
        return xml.GetPresets(presets);
    }

    bool CXmlConfig::LoadPresets(CString szFileXml, config::CPresetsList &presets)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadPresets(doc, presets);
        }
        return false;
    }

    bool CXmlConfig::SavePresets(CString szFileXml, config::CPresetsList &presets)
    {
        XmlDocumnent doc;
        XmlPresets xml(doc);
        xml.Create();
        xml.SetPresets(presets);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadFormat(XmlDocumnent &doc, config::CFormat &format)
    {
        XmlFormats xml(doc);
        return xml.GetFormat(format);
    }

    bool CXmlConfig::LoadFormat(CString szFileXml, config::CFormat &format)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadFormat(doc, format);
        }
        return false;
    }

    bool CXmlConfig::SaveFormat(CString szFileXml, config::CFormat &format)
    {
        XmlDocumnent doc;
        XmlFormats xml(doc);
        xml.Create();
        xml.SetFormat(format);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadFormats(XmlDocumnent &doc, config::CFormatsList &formats)
    {
        XmlFormats xml(doc);
        return xml.GetFormats(formats);
    }

    bool CXmlConfig::LoadFormats(CString szFileXml, config::CFormatsList &formats)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadFormats(doc, formats);
        }
        return false;
    }

    bool CXmlConfig::SaveFormats(CString szFileXml, config::CFormatsList &formats)
    {
        XmlDocumnent doc;
        XmlFormats xml(doc);
        xml.Create();
        xml.SetFormats(formats);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadTool(XmlDocumnent &doc, config::CTool &tool)
    {
        XmlTools xml(doc);
        return xml.GetTool(tool);
    }

    bool CXmlConfig::LoadTool(CString szFileXml, config::CTool &tool)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadTool(doc, tool);
        }
        return false;
    }

    bool CXmlConfig::SaveTool(CString szFileXml, config::CTool &tool)
    {
        XmlDocumnent doc;
        XmlTools xml(doc);
        xml.Create();
        xml.SetTool(tool);
        return xml.Save(szFileXml);
    }

    bool CXmlConfig::LoadTools(XmlDocumnent &doc, config::CToolsList &tools)
    {
        XmlTools xml(doc);
        return xml.GetTools(tools);
    }

    bool CXmlConfig::LoadTools(CString szFileXml, config::CToolsList &tools)
    {
        XmlDocumnent doc;
        if (XmlDoc::Open(szFileXml, doc) == true)
        {
            return LoadTools(doc, tools);
        }
        return false;
    }

    bool CXmlConfig::SaveTools(CString szFileXml, config::CToolsList &tools)
    {
        XmlDocumnent doc;
        XmlTools xml(doc);
        xml.Create();
        xml.SetTools(tools);
        return xml.Save(szFileXml);
    }
}
<commit_msg>Delete XmlConfig.cpp<commit_after><|endoftext|>


<commit_before>#include <pqxx/compiler.h>

#include <iostream>

#include <pqxx/binarystring>
#include <pqxx/connection>
#include <pqxx/transaction>
#include <pqxx/result>

using namespace PGSTD;
using namespace pqxx;

// Example program for libpqxx.  Test binarystring functionality.
//
// Usage: test062 [connect-string]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a
// backend running on host foo.bar.net, logging in as user smith.

int main(int, char *argv[])
{
  try
  {
    const string TestStr = "Nasty\n\030Test\n\t String\r\0 With Trailer\\\\\0";

    connection C(argv[1]);
    work T(C, "test62");

    T.exec("CREATE TEMP TABLE pqxxbin (binfield bytea)");
    const string Esc = escape_binary(TestStr);
    T.exec("INSERT INTO pqxxbin VALUES ('" + Esc + "')");

    result R = T.exec("SELECT * from pqxxbin");
    binarystring B( R.at(0).at(0) );

    if (B.empty())
      throw logic_error("Binary string became empty in conversion");

    if (B.size() != TestStr.size())
      throw logic_error("Binary string got changed from " +
	  to_string(TestStr.size()) + " to " + to_string(B.size()) + " bytes");

    if (strncmp(TestStr.c_str(), B.c_ptr(), B.size()) != 0)
      throw logic_error("Binary string was changed before first zero byte: "
	  "'" + string(B.c_ptr(), B.size()) + "'");

    binarystring::const_iterator c;
    binarystring::size_type i;
    for (i=0, c=B.begin(); i<B.size(); ++i, ++c)
    {
      if (c == B.end())
	throw logic_error("Premature end to binary string at " + to_string(i));

      if (B.data()[i] != TestStr.at(i))
	throw logic_error("Binary string byte " + to_string(i) + " "
	    "got changed from '" + to_string(char(TestStr[i])) + "' "
	    "to '" + to_string(char(B.data()[i])) + "'");
      if (B.at(i) != B.data()[i])
	throw logic_error("Inconsistent byte at offset " + to_string(i) + ": "
	    "operator[] says '" + to_string(char(B.at(i))) + "', "
	    "data() says '" + to_string(char(B.data()[i])) + "'");
    }
    if (c != B.end())
      throw logic_error("end() of binary string not reached");

#ifdef PQXX_HAVE_REVERSE_ITERATOR
    binarystring::const_reverse_iterator r;
    for (i=B.length(), r=B.rbegin(); i>0; --i, ++r)
    {
      if (r == B.rend())
	throw logic_error("Premature rend to binary string at " + to_string(i));

      if (B[i-1] != TestStr.at(i-1))
	throw logic_error("Reverse iterator differs at " + to_string(i));
    }
    if (r != B.rend())
      throw logic_error("rend() of binary string not reached");
#endif

    if (B.str() != TestStr)
      throw logic_error("Binary string got mangled: '" + B.str() + "'");
  }
  catch (const sql_error &e)
  {
    // If we're interested in the text of a failed query, we can write separate
    // exception handling code for this type of exception
    cerr << "SQL error: " << e.what() << endl
         << "Query was: '" << e.query() << "'" << endl;
    return 1;
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<commit_msg>Test binarystring front()/back() and swap()<commit_after>#include <pqxx/compiler.h>

#include <iostream>

#include <pqxx/binarystring>
#include <pqxx/connection>
#include <pqxx/transaction>
#include <pqxx/result>

using namespace PGSTD;
using namespace pqxx;

// Example program for libpqxx.  Test binarystring functionality.
//
// Usage: test062 [connect-string]
//
// Where connect-string is a set of connection options in Postgresql's
// PQconnectdb() format, eg. "dbname=template1" to select from a database
// called template1, or "host=foo.bar.net user=smith" to connect to a
// backend running on host foo.bar.net, logging in as user smith.

int main(int, char *argv[])
{
  try
  {
    const string TestStr = "Nasty\n\030Test\n\t String\r\0 With Trailer\\\\\0";

    connection C(argv[1]);
    work T(C, "test62");

    T.exec("CREATE TEMP TABLE pqxxbin (binfield bytea)");
    const string Esc = escape_binary(TestStr);
    T.exec("INSERT INTO pqxxbin VALUES ('" + Esc + "')");

    result R = T.exec("SELECT * from pqxxbin");
    T.exec("DELETE FROM pqxxbin");

    binarystring B( R.at(0).at(0) );

    if (B.empty())
      throw logic_error("Binary string became empty in conversion");

    if (B.size() != TestStr.size())
      throw logic_error("Binary string got changed from " +
	  to_string(TestStr.size()) + " to " + to_string(B.size()) + " bytes");

    if (strncmp(TestStr.c_str(), B.c_ptr(), B.size()) != 0)
      throw logic_error("Binary string was changed before first zero byte: "
	  "'" + string(B.c_ptr(), B.size()) + "'");

    binarystring::const_iterator c;
    binarystring::size_type i;
    for (i=0, c=B.begin(); i<B.size(); ++i, ++c)
    {
      if (c == B.end())
	throw logic_error("Premature end to binary string at " + to_string(i));

      if (B.data()[i] != TestStr.at(i))
	throw logic_error("Binary string byte " + to_string(i) + " "
	    "got changed from '" + to_string(char(TestStr[i])) + "' "
	    "to '" + to_string(char(B.data()[i])) + "'");
      if (B.at(i) != B.data()[i])
	throw logic_error("Inconsistent byte at offset " + to_string(i) + ": "
	    "operator[] says '" + to_string(char(B.at(i))) + "', "
	    "data() says '" + to_string(char(B.data()[i])) + "'");
    }
    if (B.at(0) != B.front())
      throw logic_error("Something wrong with binarystring::front()");
    if (c != B.end())
      throw logic_error("end() of binary string not reached");
    --c;
    if (*c != B.back())
      throw logic_error("Something wrong with binarystring::back()");

#ifdef PQXX_HAVE_REVERSE_ITERATOR
    binarystring::const_reverse_iterator r;
    for (i=B.length(), r=B.rbegin(); i>0; --i, ++r)
    {
      if (r == B.rend())
	throw logic_error("Premature rend to binary string at " + to_string(i));

      if (B[i-1] != TestStr.at(i-1))
	throw logic_error("Reverse iterator differs at " + to_string(i));
    }
    if (r != B.rend())
      throw logic_error("rend() of binary string not reached");
#endif

    if (B.str() != TestStr)
      throw logic_error("Binary string got mangled: '" + B.str() + "'");

    const string TestStr2("(More conventional text)");
    T.exec("INSERT INTO pqxxbin VALUES ('" + TestStr2 + "')");
    R = T.exec("SELECT * FROM pqxxbin");
    binarystring B2(R.front().front());

    if (B2 == B)
      throw logic_error("Two different binarystrings say they're equal!");
    if (!(B2 != B))
      throw logic_error("Problem with binarystring::operator!=");

    binarystring B1c(B), B2c(B2);
    if (B1c != B)
      throw logic_error("Copied binarystring differs from original");
    if (!(B2c == B2))
      throw logic_error("Copied binarystring not equal to original");

    B1c.swap(B2c);

    if (B2c == B1c)
      throw logic_error("Swapped binarystrings say they're identical!");
    if (B2c != B)
      throw logic_error("Problem with binarystring::swap()");
    if (!(B1c == B2))
      throw logic_error("Problem with one of two swapped binarystrings");
  }
  catch (const sql_error &e)
  {
    // If we're interested in the text of a failed query, we can write separate
    // exception handling code for this type of exception
    cerr << "SQL error: " << e.what() << endl
         << "Query was: '" << e.query() << "'" << endl;
    return 1;
  }
  catch (const exception &e)
  {
    // All exceptions thrown by libpqxx are derived from std::exception
    cerr << "Exception: " << e.what() << endl;
    return 2;
  }
  catch (...)
  {
    // This is really unexpected (see above)
    cerr << "Unhandled exception" << endl;
    return 100;
  }

  return 0;
}

<|endoftext|>


<commit_before>/*
Copyright (C) 2011-2012 Yubico AB.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

   1. Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "yubikeywriter.h"
#include "yubikeyfinder.h"
#include "yubikeylogger.h"

YubiKeyWriter* YubiKeyWriter::_instance = 0;

#define TKTFLAG(f, s) \
if(s) { if (!ykp_set_tktflag_##f(cfg, s)) { error = true; throw 0; } }

#define CFGFLAG(f, s) \
if(s) { if (!ykp_set_cfgflag_##f(cfg, s)) { error = true; throw 0; } }

#define EXTFLAG(f, s) \
if(s) { if (!ykp_set_extflag_##f(cfg, s)) { error = true; throw 0; } }

static int writer(const char *buf, size_t count, void *stream) {
    return (int)fwrite(buf, 1, count, (FILE *)stream);
}

YubiKeyWriter::YubiKeyWriter() {
}

YubiKeyWriter::~YubiKeyWriter() {
    if(_instance) {
        delete _instance;
    }
}

YubiKeyWriter* YubiKeyWriter::getInstance() {
    if(_instance == NULL) {
        _instance = new YubiKeyWriter();
    }
    return _instance;
}

QString YubiKeyWriter::reportError() {
    QString errMsg;

    if (ykp_errno) {
        qDebug("Yubikey personalization error: %s\n", ykp_strerror(ykp_errno));

        switch(ykp_errno) {
        case YKP_EYUBIKEYVER:
        case YKP_EOLDYUBIKEY:
            errMsg = ERR_FEATURE_NOT_SUPPORTED;
            break;
        default:
            errMsg = ERR_PROCESSING;
            break;
        }
        ykp_errno = 0;
    } else if (yk_errno) {
        if (yk_errno == YK_EUSBERR) {
            qDebug("USB error: %s\n", yk_usb_strerror());
        } else {
            qDebug("Yubikey core error: %s\n", yk_strerror(yk_errno));
        }

        switch(yk_errno) {
        case YK_ENOKEY:
            errMsg = ERR_KEY_NOT_FOUND;
            break;
        case YK_EFIRMWARE:
            errMsg = ERR_FIRMWARE_NOT_SUPPORTED;
            break;
        default:
            errMsg = ERR_PROCESSING;
            break;
        }
        yk_errno = 0;
    }

    if(!errMsg.isEmpty()) {
        emit errorOccurred(errMsg);
    }

    return errMsg;
}

void YubiKeyWriter::writeConfig(YubiKeyConfig *ykConfig) {
    // Check features support
    bool flagSrNoSupport = false;
    if(YubiKeyFinder::getInstance()->checkFeatureSupport(
            YubiKeyFinder::Feature_SerialNumber)) {
        flagSrNoSupport = true;
    }

    YubiKeyFinder::getInstance()->stop();

    YK_KEY *yk = 0;
    YK_STATUS *ykst = ykds_alloc();
    YKP_CONFIG *cfg = ykp_create_config();

    bool error = false;

    qDebug() << "-------------------------";
    qDebug() << "Starting write config";
    qDebug() << "-------------------------";

    try {
        if (!yk_init()) {
            throw 0;
        } else if (!(yk = yk_open_first_key())) {
            throw 0;
        } else if (!yk_get_status(yk, ykst)) {
            throw 0;
        }

        if (!(yk_check_firmware_version(yk))) {
            throw 0;
        }

        qDebug() << "writer:configuration slot:" << ykConfig->configSlot();

        //Configuration slot...
        if (!ykp_configure_for(cfg, ykConfig->configSlot(), ykst)) {
            throw 0;
        }

        struct config_st *ycfg = (struct config_st *) ykp_core_config(cfg);

        //Reset the default flags (particularly for slot 2)
        ycfg->tktFlags = 0;
        ycfg->cfgFlags = 0;
        ycfg->extFlags = 0;

        //Programming Mode...
        bool longSecretKey = false;

        switch(ykConfig->programmingMode()) {
        case YubiKeyConfig::Mode_YubicoOtp:
            break;

        case YubiKeyConfig::Mode_Static:
            CFGFLAG(STATIC_TICKET,      ykConfig->staticTicket());
            CFGFLAG(SHORT_TICKET,       ykConfig->shortTicket());
            CFGFLAG(STRONG_PW1,         ykConfig->strongPw1());
            CFGFLAG(STRONG_PW2,         ykConfig->strongPw2());
            CFGFLAG(MAN_UPDATE,         ykConfig->manUpdate());
            CFGFLAG(SEND_REF,           ykConfig->sendRef());
            break;

        case YubiKeyConfig::Mode_OathHotp:
            TKTFLAG(OATH_HOTP, true);

            CFGFLAG(OATH_HOTP8,         ykConfig->oathHotp8());
            CFGFLAG(OATH_FIXED_MODHEX1, ykConfig->oathFixedModhex1());
            CFGFLAG(OATH_FIXED_MODHEX2, ykConfig->oathFixedModhex2());
            CFGFLAG(OATH_FIXED_MODHEX,  ykConfig->oathFixedModhex());

            //Moving Factor Seed...
            ycfg->uid[4] = (unsigned char) (ykConfig->oathMovingFactorSeed() >> 8U);
            ycfg->uid[5] = (unsigned char) ykConfig->oathMovingFactorSeed();

            //For OATH-HOTP, 160 bits key is also valid
            longSecretKey = true;
            break;

        case YubiKeyConfig::Mode_ChalRespYubico:
            TKTFLAG(CHAL_RESP, true);

            CFGFLAG(CHAL_YUBICO,        ykConfig->chalYubico());
            CFGFLAG(CHAL_BTN_TRIG,      ykConfig->chalBtnTrig());
            break;

        case YubiKeyConfig::Mode_ChalRespHmac:
            TKTFLAG(CHAL_RESP, true);

            CFGFLAG(CHAL_HMAC,          ykConfig->chalHmac());
            CFGFLAG(HMAC_LT64,          ykConfig->hmacLT64());
            CFGFLAG(CHAL_BTN_TRIG,      ykConfig->chalBtnTrig());

            //For HMAC (not Yubico) challenge-response, 160 bits key is also valid
            longSecretKey = true;
            break;
        }

        //Public ID...
        if(ykConfig->pubIdTxt().length() > 0) {
            qDebug() << "Pub id: " << ykConfig->pubIdTxt()
                    << "length:" << ykConfig->pubIdTxt().length();

            char pubIdStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(pubIdStr, sizeof(pubIdStr),
                                   ykConfig->pubIdTxt());
            size_t pubIdStrLen = strlen(pubIdStr);

            unsigned char pubId[MAX_SIZE];
            size_t pubIdLen = 0;

            int rc = YubiKeyUtil::hexModhexDecode(pubId, &pubIdLen,
                                                  pubIdStr, pubIdStrLen,
                                                  0, FIXED_SIZE * 2,
                                                  !ykConfig->pubIdInHex());

            if (rc <= 0) {
                qDebug("Invalid public id: %s", pubIdStr);
                throw 0;
            }
            ykp_set_fixed(cfg, pubId, pubIdLen);
        }

        //Private ID...
        if(ykConfig->pvtIdTxt().length() > 0) {
            qDebug() << "Pvt id: " << ykConfig->pvtIdTxt()
                    << "length:" << ykConfig->pvtIdTxt().length();

            char pvtIdStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(pvtIdStr, sizeof(pvtIdStr),
                                   ykConfig->pvtIdTxt());
            size_t pvtIdStrLen = strlen(pvtIdStr);

            unsigned char pvtId[MAX_SIZE];
            size_t pvtIdLen = 0;

            int rc = YubiKeyUtil::hexModhexDecode(pvtId, &pvtIdLen,
                                                  pvtIdStr, pvtIdStrLen,
                                                  UID_SIZE * 2,
                                                  UID_SIZE * 2,
                                                  false);

            if (rc <= 0) {
                qDebug("Invalid private id: %s", pvtIdStr);
                throw 0;
            }
            ykp_set_uid(cfg, pvtId, pvtIdLen);
        }

        //Secret Key...
        if(ykConfig->secretKeyTxt().length() > 0) {
            qDebug() << "Secret key: " << ykConfig->secretKeyTxt()
                    << "length:" << ykConfig->secretKeyTxt().length();

            char secretKeyStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(secretKeyStr, sizeof(secretKeyStr),
                                   ykConfig->secretKeyTxt());

            int res = 0;

            if(longSecretKey && strlen(secretKeyStr) == 40) {
                res = ykp_HMAC_key_from_hex(cfg, secretKeyStr);
            } else {
                res = ykp_AES_key_from_hex(cfg, secretKeyStr);
            }

            if (res) {
                qDebug() << "Bad secret key: " << secretKeyStr;
                throw 0;
            }
        }

        //Configuration protection...
        //Current Access Code...
        unsigned char accessCode[MAX_SIZE];
        size_t accessCodeLen = 0;

        if(ykConfig->currentAccessCodeTxt().length() > 0) {
            qDebug() << "Current access code: " << ykConfig->currentAccessCodeTxt()
                    << "length:" << ykConfig->currentAccessCodeTxt().length();

            char accessCodeStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(accessCodeStr, sizeof(accessCodeStr),
                                   ykConfig->currentAccessCodeTxt());
            size_t accessCodeStrLen = strlen(accessCodeStr);

            int rc = YubiKeyUtil::hexModhexDecode(accessCode, &accessCodeLen,
                                                  accessCodeStr, accessCodeStrLen,
                                                  ACC_CODE_SIZE * 2,
                                                  ACC_CODE_SIZE * 2,
                                                  false);

            if (rc <= 0) {
                qDebug() << "Invalid current access code: " << accessCodeStr;
                throw 0;
            }
        }

        //New Access Code...
        unsigned char newAccessCode[MAX_SIZE];
        size_t newAccessCodeLen = 0;

        if(ykConfig->newAccessCodeTxt().length() > 0) {
            qDebug() << "New access code: " << ykConfig->newAccessCodeTxt()
                    << "length:" << ykConfig->newAccessCodeTxt().length();

            char newAccessCodeStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(newAccessCodeStr, sizeof(newAccessCodeStr),
                                   ykConfig->newAccessCodeTxt());
            size_t newAccessCodeStrLen = strlen(newAccessCodeStr);

            int rc = YubiKeyUtil::hexModhexDecode(newAccessCode, &newAccessCodeLen,
                                                  newAccessCodeStr, newAccessCodeStrLen,
                                                  ACC_CODE_SIZE * 2,
                                                  ACC_CODE_SIZE * 2,
                                                  false);

            if (rc <= 0) {
                qDebug() << "Invalid new access code: " << newAccessCodeStr;
                throw 0;
            }
        }

        bool useAccessCode = false;
        if(accessCodeLen > 0) {
            useAccessCode = true;
        }

        if(newAccessCodeLen > 0) {
            //Enable/change protection
            ykp_set_access_code(cfg, newAccessCode, newAccessCodeLen);

        } else if(accessCodeLen > 0) {
            //Keep same protection
            ykp_set_access_code(cfg, accessCode, accessCodeLen);
        }

        //Output parameters...
        QSettings settings;

        TKTFLAG(TAB_FIRST,          settings.value(SG_TAB_FIRST).toBool());
        TKTFLAG(APPEND_TAB1,        settings.value(SG_APPEND_TAB1).toBool());
        TKTFLAG(APPEND_TAB2,        settings.value(SG_APPEND_TAB2).toBool());
        TKTFLAG(APPEND_CR,          settings.value(SG_APPEND_CR).toBool());
        TKTFLAG(APPEND_DELAY1,      settings.value(SG_APPEND_DELAY1).toBool());
        TKTFLAG(APPEND_DELAY2,      settings.value(SG_APPEND_DELAY2).toBool());
        //TKTFLAG(PROTECT_CFG2,     ykConfig->protectCfg2());

        //CFGFLAG(SEND_REF,         ykConfig->sendRef());
        //CFGFLAG(TICKET_FIRST,     ykConfig->ticketFirst());
        CFGFLAG(PACING_10MS,        settings.value(SG_PACING_10MS).toBool());
        CFGFLAG(PACING_20MS,        settings.value(SG_PACING_20MS).toBool());
        //CFGFLAG(ALLOW_HIDTRIG,    ykConfig->allowHidtrig());

        //Serial # visibility...
        if(flagSrNoSupport) {
            EXTFLAG(SERIAL_BTN_VISIBLE, settings.value(SG_SR_BTN_VISIBLE).toBool());
            EXTFLAG(SERIAL_USB_VISIBLE, settings.value(SG_SR_USB_VISIBLE).toBool());
            EXTFLAG(SERIAL_API_VISIBLE, settings.value(SG_SR_API_VISIBLE).toBool());
        }

        //Log configuration...
        qDebug() << "-------------------------";
        qDebug() << "Config data to be written to key configuration...";

        ykp_write_config(cfg, writer, stderr);

        qDebug() << "-------------------------";

        // Write configuration...
        if (!yk_write_config(yk,
                             ykp_core_config(cfg), ykp_config_num(cfg),
                             useAccessCode ? accessCode : NULL)) {
            qDebug() << "Failure";
            throw 0;
        }
        qDebug() << "Success... config written";

        YubiKeyLogger::logConfig(ykConfig);
        emit configWritten(true, NULL);
    }
    catch(...) {
        error = true;
    }

    if (cfg) {
        ykp_free_config(cfg);
    }

    if(ykst) {
        ykds_free(ykst);
    }

    if (yk && !yk_close_key(yk)) {
        error = true;
    }

    if (!yk_release()) {
        error = true;
    }

    YubiKeyFinder::getInstance()->start();

    if(error) {
        qDebug() << "Config not written";
        QString errMsg = reportError();
        emit configWritten(false, errMsg);
    }

    qDebug() << "-------------------------";
    qDebug() << "Stopping write config";
    qDebug() << "-------------------------";
}
<commit_msg>updates for new api in ykpers 1.7<commit_after>/*
Copyright (C) 2011-2012 Yubico AB.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

   1. Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "yubikeywriter.h"
#include "yubikeyfinder.h"
#include "yubikeylogger.h"

YubiKeyWriter* YubiKeyWriter::_instance = 0;

#define TKTFLAG(f, s) \
if(s) { if (!ykp_set_tktflag_##f(cfg, s)) { error = true; throw 0; } }

#define CFGFLAG(f, s) \
if(s) { if (!ykp_set_cfgflag_##f(cfg, s)) { error = true; throw 0; } }

#define EXTFLAG(f, s) \
if(s) { if (!ykp_set_extflag_##f(cfg, s)) { error = true; throw 0; } }

static int writer(const char *buf, size_t count, void *stream) {
    return (int)fwrite(buf, 1, count, (FILE *)stream);
}

YubiKeyWriter::YubiKeyWriter() {
}

YubiKeyWriter::~YubiKeyWriter() {
    if(_instance) {
        delete _instance;
    }
}

YubiKeyWriter* YubiKeyWriter::getInstance() {
    if(_instance == NULL) {
        _instance = new YubiKeyWriter();
    }
    return _instance;
}

QString YubiKeyWriter::reportError() {
    QString errMsg;

    if (ykp_errno) {
        qDebug("Yubikey personalization error: %s\n", ykp_strerror(ykp_errno));

        switch(ykp_errno) {
        case YKP_EYUBIKEYVER:
        case YKP_EOLDYUBIKEY:
            errMsg = ERR_FEATURE_NOT_SUPPORTED;
            break;
        default:
            errMsg = ERR_PROCESSING;
            break;
        }
        ykp_errno = 0;
    } else if (yk_errno) {
        if (yk_errno == YK_EUSBERR) {
            qDebug("USB error: %s\n", yk_usb_strerror());
        } else {
            qDebug("Yubikey core error: %s\n", yk_strerror(yk_errno));
        }

        switch(yk_errno) {
        case YK_ENOKEY:
            errMsg = ERR_KEY_NOT_FOUND;
            break;
        case YK_EFIRMWARE:
            errMsg = ERR_FIRMWARE_NOT_SUPPORTED;
            break;
        default:
            errMsg = ERR_PROCESSING;
            break;
        }
        yk_errno = 0;
    }

    if(!errMsg.isEmpty()) {
        emit errorOccurred(errMsg);
    }

    return errMsg;
}

void YubiKeyWriter::writeConfig(YubiKeyConfig *ykConfig) {
    // Check features support
    bool flagSrNoSupport = false;
    if(YubiKeyFinder::getInstance()->checkFeatureSupport(
            YubiKeyFinder::Feature_SerialNumber)) {
        flagSrNoSupport = true;
    }

    YubiKeyFinder::getInstance()->stop();

    YK_KEY *yk = 0;
    YK_STATUS *ykst = ykds_alloc();
    YKP_CONFIG *cfg = ykp_alloc();

    bool error = false;

    qDebug() << "-------------------------";
    qDebug() << "Starting write config";
    qDebug() << "-------------------------";

    try {
        if (!yk_init()) {
            throw 0;
        } else if (!(yk = yk_open_first_key())) {
            throw 0;
        } else if (!yk_get_status(yk, ykst)) {
            throw 0;
        }

        if (!(yk_check_firmware_version(yk))) {
            throw 0;
        }

        ykp_configure_version(cfg, ykst);

        qDebug() << "writer:configuration slot:" << ykConfig->configSlot();

        //Configuration slot...
        if (!ykp_configure_command(cfg,
              ykConfig->configSlot() == 2 ? SLOT_CONFIG2 : SLOT_CONFIG)) {
            throw 0;
        }

        struct config_st *ycfg = (struct config_st *) ykp_core_config(cfg);

        //Reset the default flags (particularly for slot 2)
        ycfg->tktFlags = 0;
        ycfg->cfgFlags = 0;
        ycfg->extFlags = 0;

        //Programming Mode...
        bool longSecretKey = false;

        switch(ykConfig->programmingMode()) {
        case YubiKeyConfig::Mode_YubicoOtp:
            break;

        case YubiKeyConfig::Mode_Static:
            CFGFLAG(STATIC_TICKET,      ykConfig->staticTicket());
            CFGFLAG(SHORT_TICKET,       ykConfig->shortTicket());
            CFGFLAG(STRONG_PW1,         ykConfig->strongPw1());
            CFGFLAG(STRONG_PW2,         ykConfig->strongPw2());
            CFGFLAG(MAN_UPDATE,         ykConfig->manUpdate());
            CFGFLAG(SEND_REF,           ykConfig->sendRef());
            break;

        case YubiKeyConfig::Mode_OathHotp:
            TKTFLAG(OATH_HOTP, true);

            CFGFLAG(OATH_HOTP8,         ykConfig->oathHotp8());
            CFGFLAG(OATH_FIXED_MODHEX1, ykConfig->oathFixedModhex1());
            CFGFLAG(OATH_FIXED_MODHEX2, ykConfig->oathFixedModhex2());
            CFGFLAG(OATH_FIXED_MODHEX,  ykConfig->oathFixedModhex());

            //Moving Factor Seed...
            ycfg->uid[4] = (unsigned char) (ykConfig->oathMovingFactorSeed() >> 8U);
            ycfg->uid[5] = (unsigned char) ykConfig->oathMovingFactorSeed();

            //For OATH-HOTP, 160 bits key is also valid
            longSecretKey = true;
            break;

        case YubiKeyConfig::Mode_ChalRespYubico:
            TKTFLAG(CHAL_RESP, true);

            CFGFLAG(CHAL_YUBICO,        ykConfig->chalYubico());
            CFGFLAG(CHAL_BTN_TRIG,      ykConfig->chalBtnTrig());
            break;

        case YubiKeyConfig::Mode_ChalRespHmac:
            TKTFLAG(CHAL_RESP, true);

            CFGFLAG(CHAL_HMAC,          ykConfig->chalHmac());
            CFGFLAG(HMAC_LT64,          ykConfig->hmacLT64());
            CFGFLAG(CHAL_BTN_TRIG,      ykConfig->chalBtnTrig());

            //For HMAC (not Yubico) challenge-response, 160 bits key is also valid
            longSecretKey = true;
            break;
        }

        //Public ID...
        if(ykConfig->pubIdTxt().length() > 0) {
            qDebug() << "Pub id: " << ykConfig->pubIdTxt()
                    << "length:" << ykConfig->pubIdTxt().length();

            char pubIdStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(pubIdStr, sizeof(pubIdStr),
                                   ykConfig->pubIdTxt());
            size_t pubIdStrLen = strlen(pubIdStr);

            unsigned char pubId[MAX_SIZE];
            size_t pubIdLen = 0;

            int rc = YubiKeyUtil::hexModhexDecode(pubId, &pubIdLen,
                                                  pubIdStr, pubIdStrLen,
                                                  0, FIXED_SIZE * 2,
                                                  !ykConfig->pubIdInHex());

            if (rc <= 0) {
                qDebug("Invalid public id: %s", pubIdStr);
                throw 0;
            }
            ykp_set_fixed(cfg, pubId, pubIdLen);
        }

        //Private ID...
        if(ykConfig->pvtIdTxt().length() > 0) {
            qDebug() << "Pvt id: " << ykConfig->pvtIdTxt()
                    << "length:" << ykConfig->pvtIdTxt().length();

            char pvtIdStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(pvtIdStr, sizeof(pvtIdStr),
                                   ykConfig->pvtIdTxt());
            size_t pvtIdStrLen = strlen(pvtIdStr);

            unsigned char pvtId[MAX_SIZE];
            size_t pvtIdLen = 0;

            int rc = YubiKeyUtil::hexModhexDecode(pvtId, &pvtIdLen,
                                                  pvtIdStr, pvtIdStrLen,
                                                  UID_SIZE * 2,
                                                  UID_SIZE * 2,
                                                  false);

            if (rc <= 0) {
                qDebug("Invalid private id: %s", pvtIdStr);
                throw 0;
            }
            ykp_set_uid(cfg, pvtId, pvtIdLen);
        }

        //Secret Key...
        if(ykConfig->secretKeyTxt().length() > 0) {
            qDebug() << "Secret key: " << ykConfig->secretKeyTxt()
                    << "length:" << ykConfig->secretKeyTxt().length();

            char secretKeyStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(secretKeyStr, sizeof(secretKeyStr),
                                   ykConfig->secretKeyTxt());

            int res = 0;

            if(longSecretKey && strlen(secretKeyStr) == 40) {
                res = ykp_HMAC_key_from_hex(cfg, secretKeyStr);
            } else {
                res = ykp_AES_key_from_hex(cfg, secretKeyStr);
            }

            if (res) {
                qDebug() << "Bad secret key: " << secretKeyStr;
                throw 0;
            }
        }

        //Configuration protection...
        //Current Access Code...
        unsigned char accessCode[MAX_SIZE];
        size_t accessCodeLen = 0;

        if(ykConfig->currentAccessCodeTxt().length() > 0) {
            qDebug() << "Current access code: " << ykConfig->currentAccessCodeTxt()
                    << "length:" << ykConfig->currentAccessCodeTxt().length();

            char accessCodeStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(accessCodeStr, sizeof(accessCodeStr),
                                   ykConfig->currentAccessCodeTxt());
            size_t accessCodeStrLen = strlen(accessCodeStr);

            int rc = YubiKeyUtil::hexModhexDecode(accessCode, &accessCodeLen,
                                                  accessCodeStr, accessCodeStrLen,
                                                  ACC_CODE_SIZE * 2,
                                                  ACC_CODE_SIZE * 2,
                                                  false);

            if (rc <= 0) {
                qDebug() << "Invalid current access code: " << accessCodeStr;
                throw 0;
            }
        }

        //New Access Code...
        unsigned char newAccessCode[MAX_SIZE];
        size_t newAccessCodeLen = 0;

        if(ykConfig->newAccessCodeTxt().length() > 0) {
            qDebug() << "New access code: " << ykConfig->newAccessCodeTxt()
                    << "length:" << ykConfig->newAccessCodeTxt().length();

            char newAccessCodeStr[MAX_SIZE];
            YubiKeyUtil::qstrToRaw(newAccessCodeStr, sizeof(newAccessCodeStr),
                                   ykConfig->newAccessCodeTxt());
            size_t newAccessCodeStrLen = strlen(newAccessCodeStr);

            int rc = YubiKeyUtil::hexModhexDecode(newAccessCode, &newAccessCodeLen,
                                                  newAccessCodeStr, newAccessCodeStrLen,
                                                  ACC_CODE_SIZE * 2,
                                                  ACC_CODE_SIZE * 2,
                                                  false);

            if (rc <= 0) {
                qDebug() << "Invalid new access code: " << newAccessCodeStr;
                throw 0;
            }
        }

        bool useAccessCode = false;
        if(accessCodeLen > 0) {
            useAccessCode = true;
        }

        if(newAccessCodeLen > 0) {
            //Enable/change protection
            ykp_set_access_code(cfg, newAccessCode, newAccessCodeLen);

        } else if(accessCodeLen > 0) {
            //Keep same protection
            ykp_set_access_code(cfg, accessCode, accessCodeLen);
        }

        //Output parameters...
        QSettings settings;

        TKTFLAG(TAB_FIRST,          settings.value(SG_TAB_FIRST).toBool());
        TKTFLAG(APPEND_TAB1,        settings.value(SG_APPEND_TAB1).toBool());
        TKTFLAG(APPEND_TAB2,        settings.value(SG_APPEND_TAB2).toBool());
        TKTFLAG(APPEND_CR,          settings.value(SG_APPEND_CR).toBool());
        TKTFLAG(APPEND_DELAY1,      settings.value(SG_APPEND_DELAY1).toBool());
        TKTFLAG(APPEND_DELAY2,      settings.value(SG_APPEND_DELAY2).toBool());
        //TKTFLAG(PROTECT_CFG2,     ykConfig->protectCfg2());

        //CFGFLAG(SEND_REF,         ykConfig->sendRef());
        //CFGFLAG(TICKET_FIRST,     ykConfig->ticketFirst());
        CFGFLAG(PACING_10MS,        settings.value(SG_PACING_10MS).toBool());
        CFGFLAG(PACING_20MS,        settings.value(SG_PACING_20MS).toBool());
        //CFGFLAG(ALLOW_HIDTRIG,    ykConfig->allowHidtrig());

        //Serial # visibility...
        if(flagSrNoSupport) {
            EXTFLAG(SERIAL_BTN_VISIBLE, settings.value(SG_SR_BTN_VISIBLE).toBool());
            EXTFLAG(SERIAL_USB_VISIBLE, settings.value(SG_SR_USB_VISIBLE).toBool());
            EXTFLAG(SERIAL_API_VISIBLE, settings.value(SG_SR_API_VISIBLE).toBool());
        }

        //Log configuration...
        qDebug() << "-------------------------";
        qDebug() << "Config data to be written to key configuration...";

        ykp_write_config(cfg, writer, stderr);

        qDebug() << "-------------------------";

        // Write configuration...
        if (!yk_write_command(yk,
                              ykp_core_config(cfg), ykp_command(cfg),
                              useAccessCode ? accessCode : NULL)) {
            qDebug() << "Failure";
            throw 0;
        }
        qDebug() << "Success... config written";

        YubiKeyLogger::logConfig(ykConfig);
        emit configWritten(true, NULL);
    }
    catch(...) {
        error = true;
    }

    if (cfg) {
        ykp_free_config(cfg);
    }

    if(ykst) {
        ykds_free(ykst);
    }

    if (yk && !yk_close_key(yk)) {
        error = true;
    }

    if (!yk_release()) {
        error = true;
    }

    YubiKeyFinder::getInstance()->start();

    if(error) {
        qDebug() << "Config not written";
        QString errMsg = reportError();
        emit configWritten(false, errMsg);
    }

    qDebug() << "-------------------------";
    qDebug() << "Stopping write config";
    qDebug() << "-------------------------";
}
<|endoftext|>


<commit_before>// File: main_community.cpp
// -- community detection, sample main file
//-----------------------------------------------------------------------------
// Community detection
// Based on the article "Fast unfolding of community hierarchies in large networks"
// Copyright (C) 2008 V. Blondel, J.-L. Guillaume, R. Lambiotte, E. Lefebvre
//
// This program must not be distributed without agreement of the above mentionned authors.
//-----------------------------------------------------------------------------
// Author   : E. Lefebvre, adapted by J.-L. Guillaume
// Email    : jean-loup.guillaume@lip6.fr
// Location : Paris, France
// Time	    : February 2008
//-----------------------------------------------------------------------------
// see readme.txt for more details

#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <unistd.h>
#include "graph_binary.h"
#include "community.h"

using namespace std;

char *filename = NULL;
char *filename_w = NULL;
char *filename_part = NULL;
int type       = UNWEIGHTED;
int nb_pass    = 0;
double precision = 0.000001;
int display_level = -2;
int k1 = 16;

bool verbose = false;

void
usage(char *prog_name, const char *more) {
  cerr << more;
  cerr << "usage: " << prog_name << " input_file [-w weight_file] [-p part_file] [-q epsilon] [-l display_level] [-v] [-h]" << endl << endl;
  cerr << "input_file: file containing the graph to decompose in communities." << endl;
  cerr << "-w file\tread the graph as a weighted one (weights are set to 1 otherwise)." << endl;
  cerr << "-p file\tstart the computation with a given partition instead of the trivial partition." << endl;
  cerr << "\tfile must contain lines \"node community\"." << endl;
  cerr << "-q eps\ta given pass stops when the modularity is increased by less than epsilon." << endl;
  cerr << "-l k\tdisplays the graph of level k rather than the hierachical structure." << endl;
  cerr << "\tif k=-1 then displays the hierarchical structure rather than the graph at a given level." << endl;
  cerr << "-v\tverbose mode: gives computation time, information about the hierarchy and modularity." << endl;
  cerr << "-h\tshow this usage message." << endl;
  exit(0);
}

void
parse_args(int argc, char **argv) {
  if (argc<2)
    usage(argv[0], "Bad arguments number\n");

  for (int i = 1; i < argc; i++) {
    if(argv[i][0] == '-') {
      switch(argv[i][1]) {
      case 'w':
	type = WEIGHTED;
        filename_w = argv[i+1];
	i++;
	break;
      case 'p':
        filename_part = argv[i+1];
	i++;
	break;
      case 'q':
	precision = atof(argv[i+1]);
	i++;
	break;
      case 'l':
	display_level = atoi(argv[i+1]);
	i++;
	break;
      case 'k':
	k1 = atoi(argv[i+1]);
	i++;
	break;
      case 'v':
	verbose=true;
	break;
      default:
	usage(argv[0], "Unknown option\n");
      }
    } else {
      if (filename==NULL)
        filename = argv[i];
      else
        usage(argv[0], "More than one filename\n");
    }
  }
}

void
display_time(const char *str) {
  time_t rawtime;
  time ( &rawtime );
  cerr << str << ": " << ctime (&rawtime);
}

int
main(int argc, char **argv) {
  srand(time(NULL)+getpid());

  parse_args(argc, argv);
  time_t time_begin, time_end;
  time(&time_begin);
  if (verbose)
    display_time("Begin");

  Community c(filename, filename_w, type, -1, precision);
  if (filename_part!=NULL)
    c.init_partition(filename_part);
  Graph g;
  bool improvement=true;
  double mod=c.modularity(), new_mod;
  int level=0;

  do {
    if (verbose) {
      cerr << "level " << level << ":\n";
      display_time("  start computation");
      cerr << "  network size: "
	   << c.g.nb_nodes << " nodes, "
	   << c.g.nb_links << " links, "
	   << c.g.total_weight << " weight." << endl;
    }

    improvement = c.one_level();
    new_mod = c.modularity();
    if (++level==display_level)
      g.display();
    if (display_level==-1)
      c.display_partition();
    g = c.partition2graph_binary();
    c = Community(g, -1, precision);

    if (verbose)
      cerr << "  modularity increased from " << mod << " to " << new_mod << endl;

    mod=new_mod;
    if (verbose)
      display_time("  end computation");

    if (filename_part!=NULL && level==1) // do at least one more computation if partition is provided
      improvement=true;
  } while(improvement);

  time(&time_end);
  if (verbose) {
    display_time("End");
    cerr << "Total duration: " << (time_end-time_begin) << " sec." << endl;
  }
  cerr << new_mod << endl;
}

<commit_msg>Delete main_community.cpp<commit_after><|endoftext|>


<commit_before>//
// Copyright 2018 Sergei Blagodarin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <yttrium/gui/font.h>

#include <yttrium/exceptions.h>
#include <yttrium/image.h>
#include <yttrium/math/size.h>
#include <yttrium/renderer/manager.h>
#include <yttrium/renderer/texture.h>
#include <yttrium/storage/reader.h>
#include <yttrium/storage/source.h>
#include "font_data.h"
#include "texture_font.h"

#include <cassert>
#include <cstring>

#include <ft2build.h>
#include FT_FREETYPE_H

namespace Yttrium
{
	struct FreeTypeWrapper
	{
		FT_Library _library = nullptr;
		Buffer _face_buffer;
		FT_Face _face = nullptr;

		FreeTypeWrapper()
		{
			if (FT_Init_FreeType(&_library))
				throw InitializationError{ "Failed to initialize FreeType library" };
		}

		~FreeTypeWrapper() noexcept
		{
			if (_face)
				FT_Done_Face(_face);    // TODO: Handle error code.
			FT_Done_FreeType(_library); // TODO: Handle error code.
		}

		void load(Buffer&& buffer)
		{
			assert(!_face);
			if (buffer.size() > std::numeric_limits<FT_Long>::max()
				|| FT_New_Memory_Face(_library, static_cast<const FT_Byte*>(buffer.data()), static_cast<FT_Long>(buffer.size()), 0, &_face))
				throw DataError{ "Failed to load font" };
			_face_buffer = std::move(buffer);
		}
	};

	class FontImpl : public Font
	{
	public:
		FontImpl(const Source& source, RenderManager& render_manager, std::size_t size)
		{
			_freetype.emplace();
			_freetype->load(source.to_buffer());
			const ImageFormat image_format{ size * 16, size * 8, PixelFormat::Gray8 };
			Image image{ image_format };
			std::unordered_map<char, FontChar> chars;
			FT_Set_Pixel_Sizes(_freetype->_face, 0, static_cast<FT_UInt>(size));
			std::size_t x_offset = 0;
			std::size_t y_offset = 0;
			for (FT_UInt char_code = 0; char_code < 128; ++char_code)
			{
				if (FT_Load_Char(_freetype->_face, char_code, FT_LOAD_RENDER))
					continue; // TODO: Report error.
				if (_freetype->_face->glyph->bitmap.width > image_format.width() - x_offset)
				{
					x_offset = 0;
					y_offset += size;
				}
				if (_freetype->_face->glyph->bitmap.rows > image_format.height() - y_offset)
					break; // TODO: Report error.
				auto src = _freetype->_face->glyph->bitmap.buffer;
				auto dst = static_cast<std::uint8_t*>(image.data()) + image_format.row_size() * y_offset + x_offset;
				for (unsigned y = 0; y < _freetype->_face->glyph->bitmap.rows; ++y)
				{
					std::memcpy(dst, src, _freetype->_face->glyph->bitmap.width);
					src += _freetype->_face->glyph->bitmap.width;
					dst += image_format.row_size();
				}
				auto& font_char = chars[static_cast<char>(char_code)];
				font_char.rect = { { static_cast<int>(x_offset), static_cast<int>(y_offset) }, Size{ static_cast<int>(_freetype->_face->glyph->bitmap.width), static_cast<int>(_freetype->_face->glyph->bitmap.rows) } };
				font_char.offset = { 0, 0 };
				font_char.advance = font_char.rect.width();
				x_offset += _freetype->_face->glyph->bitmap.width;
			}
			_texture = render_manager.create_texture_2d(std::move(image), RenderManager::TextureFlag::Intensity);
			_data._size = static_cast<int>(size);
			_data._chars = std::move(chars);
			_data._kernings.clear();
		}

		FontImpl(const Source& source, const std::shared_ptr<const Texture2D>& texture)
			: _texture{ texture }
		{
			Reader reader{ source };

			std::uint32_t fourcc = 0;
			if (!reader.read(fourcc) || fourcc != FourccYtf1)
				throw DataError("Bad 'YTF1' fourcc");

			if (!reader.read(fourcc) || fourcc != FourccFont)
				throw DataError("Bad 'font' section fourcc");

			Ytf1Font font_section;
			if (!reader.read(font_section))
				throw DataError("Bad 'font' section");

			if (!reader.read(fourcc) || fourcc != FourccChar)
				throw DataError("Bad 'char' section fourcc");

			std::uint8_t char_count = 0;
			if (!reader.read(char_count))
				throw DataError("Bad 'char' section header");

			_data._size = font_section.size;

			Size font_rect_size;
			for (uint8_t i = 0; i < char_count; ++i)
			{
				Ytf1Char char_data;
				if (!reader.read(char_data))
					throw DataError("Bad 'char' section entry ", i);

				FontChar info;
				info.rect = { { font_section.base_x + char_data.x, font_section.base_y + char_data.y }, Size{ char_data.width, char_data.height } };
				info.offset = { char_data.x_offset, char_data.y_offset };
				info.advance = char_data.advance;

				_data._chars[char_data.id] = info;
				font_rect_size = { std::max(font_rect_size._width, char_data.x + char_data.width), std::max(font_rect_size._height, char_data.y + char_data.height) };
			}

			if (!Rect(texture->size()).contains({ { font_section.base_x, font_section.base_y }, font_rect_size }))
				throw DataError{ "Font texture size mismatch" };

			if (reader.read(fourcc))
			{
				if (fourcc != FourccKern)
					throw DataError("Bad 'kern' section fourcc");

				std::uint16_t kerning_count = 0;
				if (!reader.read(kerning_count))
					throw DataError("Bad 'kern' section header");

				for (std::uint16_t i = 0; i < kerning_count; ++i)
				{
					Ytf1Kerning kerning;
					if (!reader.read(kerning))
						throw DataError("Bad 'kern' section entry ", i);
					_data._kernings.emplace(FontData::key(kerning.first, kerning.second), kerning.amount);
				}
			}
		}

		void build(std::vector<TexturedRect>& rects, const Vector2& top_left, float font_size, std::string_view text, TextCapture* capture) const override
		{
			_data.build(rects, top_left, font_size, text, capture);
		}

		Size text_size(std::string_view text) const override
		{
			return _data.text_size(text);
		}

		SizeF text_size(std::string_view text, const SizeF& font_size) const override
		{
			return _data.text_size(text, font_size);
		}

		const Texture2D* texture() const override
		{
			return _texture.get();
		}

	private:
		FontData _data;
		std::shared_ptr<const Texture2D> _texture;
		std::optional<FreeTypeWrapper> _freetype;
	};

	std::unique_ptr<Font> Font::load(const Source& source, RenderManager& render_manager)
	{
		return std::make_unique<FontImpl>(source, render_manager, 32);
	}

	std::unique_ptr<Font> Font::load(const Source& source, const std::shared_ptr<const Texture2D>& texture)
	{
		return std::make_unique<FontImpl>(source, texture);
	}
}
<commit_msg>Fix FreeType-based text positioning<commit_after>//
// Copyright 2018 Sergei Blagodarin
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <yttrium/gui/font.h>

#include <yttrium/exceptions.h>
#include <yttrium/image.h>
#include <yttrium/math/size.h>
#include <yttrium/renderer/manager.h>
#include <yttrium/renderer/texture.h>
#include <yttrium/storage/reader.h>
#include <yttrium/storage/source.h>
#include "font_data.h"
#include "texture_font.h"

#include <cassert>
#include <cstring>

#include <ft2build.h>
#include FT_FREETYPE_H

namespace Yttrium
{
	struct FreeTypeWrapper
	{
		FT_Library _library = nullptr;
		Buffer _face_buffer;
		FT_Face _face = nullptr;

		FreeTypeWrapper()
		{
			if (FT_Init_FreeType(&_library))
				throw InitializationError{ "Failed to initialize FreeType library" };
		}

		~FreeTypeWrapper() noexcept
		{
			if (_face)
				FT_Done_Face(_face);    // TODO: Handle error code.
			FT_Done_FreeType(_library); // TODO: Handle error code.
		}

		void load(Buffer&& buffer)
		{
			assert(!_face);
			if (buffer.size() > std::numeric_limits<FT_Long>::max()
				|| FT_New_Memory_Face(_library, static_cast<const FT_Byte*>(buffer.data()), static_cast<FT_Long>(buffer.size()), 0, &_face))
				throw DataError{ "Failed to load font" };
			_face_buffer = std::move(buffer);
		}
	};

	class FontImpl : public Font
	{
	public:
		FontImpl(const Source& source, RenderManager& render_manager, std::size_t size)
		{
			_freetype.emplace();
			_freetype->load(source.to_buffer());
			const ImageFormat image_format{ size * 16, size * 8, PixelFormat::Gray8 };
			Image image{ image_format };
			std::unordered_map<char, FontChar> chars;
			FT_Set_Pixel_Sizes(_freetype->_face, 0, static_cast<FT_UInt>(size));
			std::size_t x_offset = 0;
			std::size_t y_offset = 0;
			std::size_t row_height = 0;
			const auto baseline = static_cast<FT_Int>(size) * _freetype->_face->ascender / _freetype->_face->height;
			for (FT_UInt char_code = 0; char_code < 128; ++char_code)
			{
				if (FT_Load_Char(_freetype->_face, char_code, FT_LOAD_RENDER))
					continue; // TODO: Report error.
				const auto glyph = _freetype->_face->glyph;
				if (glyph->bitmap.width > image_format.width() - x_offset)
				{
					x_offset = 0;
					y_offset += row_height + 1;
					row_height = 0;
				}
				if (glyph->bitmap.rows > image_format.height() - y_offset)
					break; // TODO: Report error.
				auto src = glyph->bitmap.buffer;
				auto dst = static_cast<std::uint8_t*>(image.data()) + image_format.row_size() * y_offset + x_offset;
				for (unsigned y = 0; y < glyph->bitmap.rows; ++y)
				{
					std::memcpy(dst, src, glyph->bitmap.width);
					src += glyph->bitmap.width;
					dst += image_format.row_size();
				}
				auto& font_char = chars[static_cast<char>(char_code)];
				font_char.rect = { { static_cast<int>(x_offset), static_cast<int>(y_offset) }, Size{ static_cast<int>(glyph->bitmap.width), static_cast<int>(glyph->bitmap.rows) } };
				font_char.offset = { glyph->bitmap_left, baseline - glyph->bitmap_top };
				font_char.advance = glyph->advance.x >> 6;
				x_offset += glyph->bitmap.width + 1;
				if (row_height < glyph->bitmap.rows)
					row_height = glyph->bitmap.rows;
			}
			_texture = render_manager.create_texture_2d(std::move(image), RenderManager::TextureFlag::Intensity);
			_data._size = static_cast<int>(size);
			_data._chars = std::move(chars);
			_data._kernings.clear();
		}

		FontImpl(const Source& source, const std::shared_ptr<const Texture2D>& texture)
			: _texture{ texture }
		{
			Reader reader{ source };

			std::uint32_t fourcc = 0;
			if (!reader.read(fourcc) || fourcc != FourccYtf1)
				throw DataError("Bad 'YTF1' fourcc");

			if (!reader.read(fourcc) || fourcc != FourccFont)
				throw DataError("Bad 'font' section fourcc");

			Ytf1Font font_section;
			if (!reader.read(font_section))
				throw DataError("Bad 'font' section");

			if (!reader.read(fourcc) || fourcc != FourccChar)
				throw DataError("Bad 'char' section fourcc");

			std::uint8_t char_count = 0;
			if (!reader.read(char_count))
				throw DataError("Bad 'char' section header");

			_data._size = font_section.size;

			Size font_rect_size;
			for (uint8_t i = 0; i < char_count; ++i)
			{
				Ytf1Char char_data;
				if (!reader.read(char_data))
					throw DataError("Bad 'char' section entry ", i);

				FontChar info;
				info.rect = { { font_section.base_x + char_data.x, font_section.base_y + char_data.y }, Size{ char_data.width, char_data.height } };
				info.offset = { char_data.x_offset, char_data.y_offset };
				info.advance = char_data.advance;

				_data._chars[char_data.id] = info;
				font_rect_size = { std::max(font_rect_size._width, char_data.x + char_data.width), std::max(font_rect_size._height, char_data.y + char_data.height) };
			}

			if (!Rect(texture->size()).contains({ { font_section.base_x, font_section.base_y }, font_rect_size }))
				throw DataError{ "Font texture size mismatch" };

			if (reader.read(fourcc))
			{
				if (fourcc != FourccKern)
					throw DataError("Bad 'kern' section fourcc");

				std::uint16_t kerning_count = 0;
				if (!reader.read(kerning_count))
					throw DataError("Bad 'kern' section header");

				for (std::uint16_t i = 0; i < kerning_count; ++i)
				{
					Ytf1Kerning kerning;
					if (!reader.read(kerning))
						throw DataError("Bad 'kern' section entry ", i);
					_data._kernings.emplace(FontData::key(kerning.first, kerning.second), kerning.amount);
				}
			}
		}

		void build(std::vector<TexturedRect>& rects, const Vector2& top_left, float font_size, std::string_view text, TextCapture* capture) const override
		{
			_data.build(rects, top_left, font_size, text, capture);
		}

		Size text_size(std::string_view text) const override
		{
			return _data.text_size(text);
		}

		SizeF text_size(std::string_view text, const SizeF& font_size) const override
		{
			return _data.text_size(text, font_size);
		}

		const Texture2D* texture() const override
		{
			return _texture.get();
		}

	private:
		FontData _data;
		std::shared_ptr<const Texture2D> _texture;
		std::optional<FreeTypeWrapper> _freetype;
	};

	std::unique_ptr<Font> Font::load(const Source& source, RenderManager& render_manager)
	{
		return std::make_unique<FontImpl>(source, render_manager, 32);
	}

	std::unique_ptr<Font> Font::load(const Source& source, const std::shared_ptr<const Texture2D>& texture)
	{
		return std::make_unique<FontImpl>(source, texture);
	}
}
<|endoftext|>


<commit_before>#include <ssh/ssh_encryption.h>

namespace {
	struct ssh_encryption_algorithm {
		const char *rfc4250_name_;
		CryptoEncryption::Algorithm crypto_algorithm_;
		CryptoEncryption::Mode crypto_mode_;
	};

	static const struct ssh_encryption_algorithm ssh_encryption_algorithms[] = {
		{ "aes128-cbc",		CryptoEncryption::AES128,	CryptoEncryption::CBC	},
		{ NULL,			CryptoEncryption::AES128,	CryptoEncryption::CBC	}
	};

	class CryptoSSHEncryption : public SSH::Encryption {
		LogHandle log_;
		const CryptoEncryption::Method *method_;
	public:
		CryptoSSHEncryption(const std::string& xname, const CryptoEncryption::Method *method)
		: SSH::Encryption(xname),
		  log_("/ssh/encryption/crypto/" + xname),
		  method_(method)
		{
			ASSERT(log_, method_ != NULL);
		}

		~CryptoSSHEncryption()
		{ }

		bool input(Buffer *)
		{
			ERROR(log_) << "Not yet implemented.";
			return (false);
		}
	};
}

SSH::Encryption *
SSH::Encryption::cipher(CryptoEncryption::Cipher cipher)
{
	const struct ssh_encryption_algorithm *alg;

	for (alg = ssh_encryption_algorithms; alg->rfc4250_name_ != NULL; alg++) {
		if (cipher.first != alg->crypto_algorithm_)
			continue;
		if (cipher.second != alg->crypto_mode_)
			continue;
		const CryptoEncryption::Method *method = CryptoEncryption::Method::method(cipher);
		if (method == NULL)
			return (NULL);
		return (new CryptoSSHEncryption(alg->rfc4250_name_, method));
	}
	return (NULL);
}
<commit_msg>Add other algorithm names.<commit_after>#include <ssh/ssh_encryption.h>

namespace {
	struct ssh_encryption_algorithm {
		const char *rfc4250_name_;
		CryptoEncryption::Algorithm crypto_algorithm_;
		CryptoEncryption::Mode crypto_mode_;
	};

	static const struct ssh_encryption_algorithm ssh_encryption_algorithms[] = {
		{ "3des-cbc",		CryptoEncryption::TripleDES,	CryptoEncryption::CBC	},
		{ "aes128-cbc",		CryptoEncryption::AES128,	CryptoEncryption::CBC	},
		{ "aes128-ctr",		CryptoEncryption::AES128,	CryptoEncryption::CTR	},
		{ "aes192-cbc",		CryptoEncryption::AES192,	CryptoEncryption::CBC	},
		{ "aes192-ctr",		CryptoEncryption::AES192,	CryptoEncryption::CTR	},
		{ "aes256-cbc",		CryptoEncryption::AES256,	CryptoEncryption::CBC	},
		{ "aes256-ctr",		CryptoEncryption::AES256,	CryptoEncryption::CTR	},
		{ NULL,			CryptoEncryption::AES128,	CryptoEncryption::CBC	}
	};

	class CryptoSSHEncryption : public SSH::Encryption {
		LogHandle log_;
		const CryptoEncryption::Method *method_;
	public:
		CryptoSSHEncryption(const std::string& xname, const CryptoEncryption::Method *method)
		: SSH::Encryption(xname),
		  log_("/ssh/encryption/crypto/" + xname),
		  method_(method)
		{
			ASSERT(log_, method_ != NULL);
		}

		~CryptoSSHEncryption()
		{ }

		bool input(Buffer *)
		{
			ERROR(log_) << "Not yet implemented.";
			return (false);
		}
	};
}

SSH::Encryption *
SSH::Encryption::cipher(CryptoEncryption::Cipher cipher)
{
	const struct ssh_encryption_algorithm *alg;

	for (alg = ssh_encryption_algorithms; alg->rfc4250_name_ != NULL; alg++) {
		if (cipher.first != alg->crypto_algorithm_)
			continue;
		if (cipher.second != alg->crypto_mode_)
			continue;
		const CryptoEncryption::Method *method = CryptoEncryption::Method::method(cipher);
		if (method == NULL)
			return (NULL);
		return (new CryptoSSHEncryption(alg->rfc4250_name_, method));
	}
	return (NULL);
}
<|endoftext|>