<commit_before>#pragma once

// std
#include <cstdint>
#include <map>

// project
#include "Type.hpp"
#include "Section.hpp"
#include "Memory.hpp"

namespace dai
{
namespace bootloader
{

namespace request {

    enum Command : uint32_t {
        USB_ROM_BOOT = 0,
        BOOT_APPLICATION,
        UPDATE_FLASH,
        GET_BOOTLOADER_VERSION,
        BOOT_MEMORY,
        UPDATE_FLASH_EX,
        UPDATE_FLASH_EX_2,
        NO_OP,
        GET_BOOTLOADER_TYPE,
        SET_BOOTLOADER_CONFIG,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
        GET_BOOTLOADER_COMMIT,
        UPDATE_FLASH_BOOT_HEADER,
        READ_FLASH,
        GET_APPLICATION_DETAILS,
        GET_MEMORY_DETAILS,
    };

    struct BaseRequest {
        BaseRequest(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct UsbRomBoot : BaseRequest {
        // Common
        UsbRomBoot() : BaseRequest(USB_ROM_BOOT) {}

        static constexpr auto VERSION = "0.0.2";
        static constexpr const char* NAME = "UsbRomBoot";
    };
    struct BootApplication : BaseRequest {
        // Common
        BootApplication() : BaseRequest(BOOT_APPLICATION) {}

        // Data

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "BootApplication";
    };

    struct UpdateFlash : BaseRequest {
        // Common
        UpdateFlash() : BaseRequest(UPDATE_FLASH) {}

        // Data
        enum Storage : uint32_t { SBR, BOOTLOADER };
        Storage storage = Storage::SBR;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "UpdateFlash";
    };

    struct GetBootloaderVersion : BaseRequest {
        // Common
        GetBootloaderVersion() : BaseRequest(GET_BOOTLOADER_VERSION) {}

        // Data

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "GetBootloaderVersion";
    };

    // 0.0.12 or higher
    struct BootMemory : BaseRequest {
        // Common
        BootMemory() : BaseRequest(BOOT_MEMORY) {}

        // Data
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "BootMemory";
    };

    // UpdateFlashEx - Additional options
    struct UpdateFlashEx : BaseRequest {
        // Common
        UpdateFlashEx() : BaseRequest(UPDATE_FLASH_EX) {}

        // Data
        Memory memory = Memory::AUTO;
        Section section = Section::AUTO;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "UpdateFlashEx";
    };

    // UpdateFlashEx2 - Additional options
    struct UpdateFlashEx2 : BaseRequest {
        // Common
        UpdateFlashEx2() : BaseRequest(UPDATE_FLASH_EX_2) {}

        // Data
        Memory memory = Memory::AUTO;
        uint32_t offset = 0; // TODO investigate type due to depthai-core assigning signed `long` to this field
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "UpdateFlashEx2";
    };

    struct GetBootloaderType : BaseRequest {
        // Common
        GetBootloaderType() : BaseRequest(GET_BOOTLOADER_TYPE) {}

        // Data

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "GetBootloaderType";
    };

    // 0.0.14 or higher
    struct SetBootloaderConfig : BaseRequest {
        // Common
        SetBootloaderConfig() : BaseRequest(SET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory = Memory::AUTO;
        int64_t offset = -1;
        uint32_t clearConfig = 0;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "SetBootloaderConfig";
    };

    struct GetBootloaderConfig : BaseRequest {
        // Common
        GetBootloaderConfig() : BaseRequest(GET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory = Memory::AUTO;
        int64_t offset = -1;
        uint32_t maxSize = 0;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "GetBootloaderConfig";
    };
    struct BootloaderMemory : BaseRequest {
        // Common
        BootloaderMemory() : BaseRequest(BOOTLOADER_MEMORY) {}

        // Data

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "BootloaderMemory";
    };

    // 0.0.18
    struct GetBootloaderCommit : BaseRequest {
        // Common
        GetBootloaderCommit() : BaseRequest(GET_BOOTLOADER_COMMIT) {}

        // Data

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "GetBootloaderCommit";
    };

    // 0.0.19
    struct UpdateFlashBootHeader : BaseRequest {
        // Common
        UpdateFlashBootHeader() : BaseRequest(UPDATE_FLASH_BOOT_HEADER) {}

        // Data
        enum Type : int32_t { GPIO_MODE = 0, USB_RECOVERY, NORMAL, FAST };

        Type type;
        int64_t offset = -1;
        int64_t location = -1;
        int32_t dummyCycles = -1;
        int32_t frequency = -1;
        int32_t gpioMode = -1;

        static constexpr const char* VERSION = "0.0.16";
        static constexpr const char* NAME = "UpdateFlashBootHeader";
    };

    struct ReadFlash : BaseRequest {
        // Common
        ReadFlash() : BaseRequest(READ_FLASH) {}

        // Data
        Memory memory = Memory::AUTO;
        uint32_t offset = 0;
        uint32_t totalSize = 0;

        static constexpr const char* VERSION = "0.0.16";
        static constexpr const char* NAME = "ReadFlash";
    };

    struct GetApplicationDetails : BaseRequest {
        // Common
        GetApplicationDetails() : BaseRequest(GET_APPLICATION_DETAILS) {}

        // Data

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "GetApplicationDetails";
    };

    struct GetMemoryDetails : BaseRequest {
        // Common
        GetMemoryDetails() : BaseRequest(GET_MEMORY_DETAILS) {}

        // Data
        Memory memory = Memory::FLASH;

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "GetMemoryDetails";
    };
}

namespace response {

    enum Command : uint32_t {
        FLASH_COMPLETE = 0,
        FLASH_STATUS_UPDATE,
        BOOTLOADER_VERSION,
        BOOTLOADER_TYPE,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
        BOOT_APPLICATION,
        BOOTLOADER_COMMIT,
        READ_FLASH,
        APPLICATION_DETAILS,
        MEMORY_DETAILS,
    };

    struct BaseResponse {
        BaseResponse(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct FlashComplete : BaseResponse {
        // Common
        FlashComplete() : BaseResponse(FLASH_COMPLETE) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "FlashComplete";
    };
    struct FlashStatusUpdate : BaseResponse {
        // Common
        FlashStatusUpdate() : BaseResponse(FLASH_STATUS_UPDATE) {}

        // Data
        float progress = 0.0f;

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "FlashStatusUpdate";
    };
    struct BootloaderVersion : BaseResponse {
        // Common
        BootloaderVersion() : BaseResponse(BOOTLOADER_VERSION) {}

        // Data
        uint32_t major = 0;
        uint32_t minor = 0;
        uint32_t patch = 0;

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "BootloaderVersion";
    };

    struct BootloaderType : BaseResponse {
        // Common
        BootloaderType() : BaseResponse(BOOTLOADER_TYPE) {}

        // Data
        Type type = Type::AUTO;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "BootloaderType";
    };

    // 0.0.14
    struct GetBootloaderConfig : BaseResponse {
        // Common
        GetBootloaderConfig() : BaseResponse(GET_BOOTLOADER_CONFIG) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "GetBootloaderConfig";
    };

    struct BootloaderMemory : BaseResponse {
        // Common
        BootloaderMemory() : BaseResponse(BOOTLOADER_MEMORY) {}

        // Data
        Memory memory = Memory::AUTO;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "BootloaderMemory";
    };

    struct BootApplication : BaseResponse {
        // Common
        BootApplication() : BaseResponse(BOOT_APPLICATION) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "BootApplication";
    };

    // 0.0.18
    struct BootloaderCommit : BaseResponse {
        // Common
        BootloaderCommit() : BaseResponse(BOOTLOADER_COMMIT) {}

        // Data
        char commitStr[64]{0};

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "BootloaderCommit";
    };

    // 0.0.19
    struct ReadFlash : BaseResponse {
        // Common
        ReadFlash() : BaseResponse(READ_FLASH) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.16";
        static constexpr const char* NAME = "ReadFlash";
    };

    struct ApplicationDetails : BaseResponse {
        // Common
        ApplicationDetails() : BaseResponse(APPLICATION_DETAILS) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};
        uint32_t hasApplication = 0;
        uint32_t hasFirmwareVersion = 0;
        uint32_t hasApplicationName = 0;
        char firmwareVersionStr[256]{0};
        char applicationNameStr[4*1024]{0};

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "ApplicationVersion";
    };

    struct MemoryDetails : BaseResponse {
        // Common
        MemoryDetails() : BaseResponse(MEMORY_DETAILS) {}

        // Data
        Memory memory = Memory::FLASH;
        int64_t memorySize = 0;
        char memoryInfo[512]{0};

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "MemoryDetails";
    };

}

} // namespace bootloader
} // namespace dai
<commit_msg>Updated versioning on added request/responses<commit_after>#pragma once

// std
#include <cstdint>
#include <map>

// project
#include "Type.hpp"
#include "Section.hpp"
#include "Memory.hpp"

namespace dai
{
namespace bootloader
{

namespace request {

    enum Command : uint32_t {
        USB_ROM_BOOT = 0,
        BOOT_APPLICATION,
        UPDATE_FLASH,
        GET_BOOTLOADER_VERSION,
        BOOT_MEMORY,
        UPDATE_FLASH_EX,
        UPDATE_FLASH_EX_2,
        NO_OP,
        GET_BOOTLOADER_TYPE,
        SET_BOOTLOADER_CONFIG,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
        GET_BOOTLOADER_COMMIT,
        UPDATE_FLASH_BOOT_HEADER,
        READ_FLASH,
        GET_APPLICATION_DETAILS,
        GET_MEMORY_DETAILS,
    };

    struct BaseRequest {
        BaseRequest(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct UsbRomBoot : BaseRequest {
        // Common
        UsbRomBoot() : BaseRequest(USB_ROM_BOOT) {}

        static constexpr auto VERSION = "0.0.2";
        static constexpr const char* NAME = "UsbRomBoot";
    };
    struct BootApplication : BaseRequest {
        // Common
        BootApplication() : BaseRequest(BOOT_APPLICATION) {}

        // Data

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "BootApplication";
    };

    struct UpdateFlash : BaseRequest {
        // Common
        UpdateFlash() : BaseRequest(UPDATE_FLASH) {}

        // Data
        enum Storage : uint32_t { SBR, BOOTLOADER };
        Storage storage = Storage::SBR;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "UpdateFlash";
    };

    struct GetBootloaderVersion : BaseRequest {
        // Common
        GetBootloaderVersion() : BaseRequest(GET_BOOTLOADER_VERSION) {}

        // Data

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "GetBootloaderVersion";
    };

    // 0.0.12 or higher
    struct BootMemory : BaseRequest {
        // Common
        BootMemory() : BaseRequest(BOOT_MEMORY) {}

        // Data
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "BootMemory";
    };

    // UpdateFlashEx - Additional options
    struct UpdateFlashEx : BaseRequest {
        // Common
        UpdateFlashEx() : BaseRequest(UPDATE_FLASH_EX) {}

        // Data
        Memory memory = Memory::AUTO;
        Section section = Section::AUTO;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "UpdateFlashEx";
    };

    // UpdateFlashEx2 - Additional options
    struct UpdateFlashEx2 : BaseRequest {
        // Common
        UpdateFlashEx2() : BaseRequest(UPDATE_FLASH_EX_2) {}

        // Data
        Memory memory = Memory::AUTO;
        uint32_t offset = 0; // TODO investigate type due to depthai-core assigning signed `long` to this field
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "UpdateFlashEx2";
    };

    struct GetBootloaderType : BaseRequest {
        // Common
        GetBootloaderType() : BaseRequest(GET_BOOTLOADER_TYPE) {}

        // Data

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "GetBootloaderType";
    };

    // 0.0.14 or higher
    struct SetBootloaderConfig : BaseRequest {
        // Common
        SetBootloaderConfig() : BaseRequest(SET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory = Memory::AUTO;
        int64_t offset = -1;
        uint32_t clearConfig = 0;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "SetBootloaderConfig";
    };

    struct GetBootloaderConfig : BaseRequest {
        // Common
        GetBootloaderConfig() : BaseRequest(GET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory = Memory::AUTO;
        int64_t offset = -1;
        uint32_t maxSize = 0;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "GetBootloaderConfig";
    };
    struct BootloaderMemory : BaseRequest {
        // Common
        BootloaderMemory() : BaseRequest(BOOTLOADER_MEMORY) {}

        // Data

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "BootloaderMemory";
    };

    // 0.0.18
    struct GetBootloaderCommit : BaseRequest {
        // Common
        GetBootloaderCommit() : BaseRequest(GET_BOOTLOADER_COMMIT) {}

        // Data

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "GetBootloaderCommit";
    };

    // 0.0.19
    struct UpdateFlashBootHeader : BaseRequest {
        // Common
        UpdateFlashBootHeader() : BaseRequest(UPDATE_FLASH_BOOT_HEADER) {}

        // Data
        enum Type : int32_t { GPIO_MODE = 0, USB_RECOVERY, NORMAL, FAST };

        Type type;
        int64_t offset = -1;
        int64_t location = -1;
        int32_t dummyCycles = -1;
        int32_t frequency = -1;
        int32_t gpioMode = -1;

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "UpdateFlashBootHeader";
    };

    struct ReadFlash : BaseRequest {
        // Common
        ReadFlash() : BaseRequest(READ_FLASH) {}

        // Data
        Memory memory = Memory::AUTO;
        uint32_t offset = 0;
        uint32_t totalSize = 0;

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "ReadFlash";
    };

    struct GetApplicationDetails : BaseRequest {
        // Common
        GetApplicationDetails() : BaseRequest(GET_APPLICATION_DETAILS) {}

        // Data
        Memory memory = Memory::FLASH;

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "GetApplicationDetails";
    };

    struct GetMemoryDetails : BaseRequest {
        // Common
        GetMemoryDetails() : BaseRequest(GET_MEMORY_DETAILS) {}

        // Data
        Memory memory = Memory::FLASH;

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "GetMemoryDetails";
    };
}

namespace response {

    enum Command : uint32_t {
        FLASH_COMPLETE = 0,
        FLASH_STATUS_UPDATE,
        BOOTLOADER_VERSION,
        BOOTLOADER_TYPE,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
        BOOT_APPLICATION,
        BOOTLOADER_COMMIT,
        READ_FLASH,
        APPLICATION_DETAILS,
        MEMORY_DETAILS,
    };

    struct BaseResponse {
        BaseResponse(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct FlashComplete : BaseResponse {
        // Common
        FlashComplete() : BaseResponse(FLASH_COMPLETE) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "FlashComplete";
    };
    struct FlashStatusUpdate : BaseResponse {
        // Common
        FlashStatusUpdate() : BaseResponse(FLASH_STATUS_UPDATE) {}

        // Data
        float progress = 0.0f;

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "FlashStatusUpdate";
    };
    struct BootloaderVersion : BaseResponse {
        // Common
        BootloaderVersion() : BaseResponse(BOOTLOADER_VERSION) {}

        // Data
        uint32_t major = 0;
        uint32_t minor = 0;
        uint32_t patch = 0;

        static constexpr const char* VERSION = "0.0.2";
        static constexpr const char* NAME = "BootloaderVersion";
    };

    struct BootloaderType : BaseResponse {
        // Common
        BootloaderType() : BaseResponse(BOOTLOADER_TYPE) {}

        // Data
        Type type = Type::AUTO;

        static constexpr const char* VERSION = "0.0.12";
        static constexpr const char* NAME = "BootloaderType";
    };

    // 0.0.14
    struct GetBootloaderConfig : BaseResponse {
        // Common
        GetBootloaderConfig() : BaseResponse(GET_BOOTLOADER_CONFIG) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "GetBootloaderConfig";
    };

    struct BootloaderMemory : BaseResponse {
        // Common
        BootloaderMemory() : BaseResponse(BOOTLOADER_MEMORY) {}

        // Data
        Memory memory = Memory::AUTO;

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "BootloaderMemory";
    };

    struct BootApplication : BaseResponse {
        // Common
        BootApplication() : BaseResponse(BOOT_APPLICATION) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};

        static constexpr const char* VERSION = "0.0.14";
        static constexpr const char* NAME = "BootApplication";
    };

    // 0.0.18
    struct BootloaderCommit : BaseResponse {
        // Common
        BootloaderCommit() : BaseResponse(BOOTLOADER_COMMIT) {}

        // Data
        char commitStr[64]{0};

        static constexpr const char* VERSION = "0.0.18";
        static constexpr const char* NAME = "BootloaderCommit";
    };

    // 0.0.19
    struct ReadFlash : BaseResponse {
        // Common
        ReadFlash() : BaseResponse(READ_FLASH) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "ReadFlash";
    };

    struct ApplicationDetails : BaseResponse {
        // Common
        ApplicationDetails() : BaseResponse(APPLICATION_DETAILS) {}

        // Data
        uint32_t success = 0;
        char errorMsg[64]{0};
        uint32_t hasApplication = 0;
        uint32_t hasFirmwareVersion = 0;
        uint32_t hasApplicationName = 0;
        char firmwareVersionStr[256]{0};
        char applicationNameStr[4*1024]{0};

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "ApplicationVersion";
    };

    struct MemoryDetails : BaseResponse {
        // Common
        MemoryDetails() : BaseResponse(MEMORY_DETAILS) {}

        // Data
        uint32_t hasMemory = 0;
        Memory memory = Memory::FLASH;
        int64_t memorySize = 0;
        char memoryInfo[512]{0};

        static constexpr const char* VERSION = "0.0.19";
        static constexpr const char* NAME = "MemoryDetails";
    };

}

} // namespace bootloader
} // namespace dai
<|endoftext|>


<commit_before>#pragma once

// std
#include <cstdint>
#include <map>

// project
#include "Type.hpp"
#include "Section.hpp"
#include "Memory.hpp"

namespace dai
{
namespace bootloader
{

namespace request {

    enum Command : uint32_t {
        USB_ROM_BOOT = 0,
        BOOT_APPLICATION,
        UPDATE_FLASH,
        GET_BOOTLOADER_VERSION,
        BOOT_MEMORY,
        UPDATE_FLASH_EX,
        UPDATE_FLASH_EX_2,
        NO_OP,
        GET_BOOTLOADER_TYPE,
        SET_BOOTLOADER_CONFIG,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
    };

    struct BaseRequest {
        BaseRequest(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct UsbRomBoot : BaseRequest {
        // Common
        UsbRomBoot() : BaseRequest(USB_ROM_BOOT) {}
    };
    struct BootApplication : BaseRequest {
        // Common
        BootApplication() : BaseRequest(BOOT_APPLICATION) {}

        // Data
    };

    struct UpdateFlash : BaseRequest {
        // Common
        UpdateFlash() : BaseRequest(UPDATE_FLASH) {}

        // Data
        enum Storage : uint32_t { SBR, BOOTLOADER };
        Storage storage;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct GetBootloaderVersion : BaseRequest {
        // Common
        GetBootloaderVersion() : BaseRequest(GET_BOOTLOADER_VERSION) {}

        // Data
    };

    // 0.0.12 or higher
    struct BootMemory : BaseRequest {
        // Common
        BootMemory() : BaseRequest(BOOT_MEMORY) {}

        // Data
        uint32_t totalSize;
        uint32_t numPackets;
    };

    // UpdateFlashEx - Additional options
    struct UpdateFlashEx : BaseRequest {
        // Common
        UpdateFlashEx() : BaseRequest(UPDATE_FLASH_EX) {}

        // Data
        Memory memory;
        Section section;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    // UpdateFlashEx2 - Additional options
    struct UpdateFlashEx2 : BaseRequest {
        // Common
        UpdateFlashEx2() : BaseRequest(UPDATE_FLASH_EX_2) {}

        // Data
        Memory memory;
        uint32_t offset;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct GetBootloaderType : BaseRequest {
        // Common
        GetBootloaderType() : BaseRequest(GET_BOOTLOADER_TYPE) {}

        // Data
    };

    // 0.0.14 or higher
    struct SetBootloaderConfig : BaseRequest {
        // Common
        SetBootloaderConfig() : BaseRequest(SET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory;
        uint32_t clearConfig;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct GetBootloaderConfig : BaseRequest {
        // Common
        GetBootloaderConfig() : BaseRequest(GET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory;
    };
    struct BootloaderMemory : BaseRequest {
        // Common
        BootloaderMemory() : BaseRequest(BOOTLOADER_MEMORY) {}

        // Data
    };

}

namespace response {

    enum Command : uint32_t {
        FLASH_COMPLETE = 0,
        FLASH_STATUS_UPDATE,
        BOOTLOADER_VERSION,
        BOOTLOADER_TYPE,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
        BOOT_APPLICATION,
    };

    struct BaseResponse {
        BaseResponse(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct FlashComplete : BaseResponse {
        // Common
        FlashComplete() : BaseResponse(FLASH_COMPLETE) {}

        // Data
        uint32_t success;
        char errorMsg[64];
    };
    struct FlashStatusUpdate : BaseResponse {
        // Common
        FlashStatusUpdate() : BaseResponse(FLASH_STATUS_UPDATE) {}

        // Data
        float progress;
    };
    struct BootloaderVersion : BaseResponse {
        // Common
        BootloaderVersion() : BaseResponse(BOOTLOADER_VERSION) {}

        // Data
        uint32_t major, minor, patch;
    };

    struct BootloaderType : BaseResponse {
        // Common
        BootloaderType() : BaseResponse(BOOTLOADER_TYPE) {}

        // Data
        Type type;
    };

    // 0.0.14
    struct GetBootloaderConfig : BaseResponse {
        // Common
        GetBootloaderConfig() : BaseResponse(GET_BOOTLOADER_CONFIG) {}

        // Data
        uint32_t success;
        char errorMsg[64];
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct BootloaderMemory : BaseResponse {
        // Common
        BootloaderMemory() : BaseResponse(BOOTLOADER_MEMORY) {}

        // Data
        Memory memory;
    };

    struct BootApplication : BaseResponse {
        // Common
        BootApplication() : BaseResponse(BOOT_APPLICATION) {}

        // Data
        uint32_t success;
        char errorMsg[64];
    };
}

} // namespace bootloader
} // namespace dai
<commit_msg>Updated BL config commands<commit_after>#pragma once

// std
#include <cstdint>
#include <map>

// project
#include "Type.hpp"
#include "Section.hpp"
#include "Memory.hpp"

namespace dai
{
namespace bootloader
{

namespace request {

    enum Command : uint32_t {
        USB_ROM_BOOT = 0,
        BOOT_APPLICATION,
        UPDATE_FLASH,
        GET_BOOTLOADER_VERSION,
        BOOT_MEMORY,
        UPDATE_FLASH_EX,
        UPDATE_FLASH_EX_2,
        NO_OP,
        GET_BOOTLOADER_TYPE,
        SET_BOOTLOADER_CONFIG,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
    };

    struct BaseRequest {
        BaseRequest(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct UsbRomBoot : BaseRequest {
        // Common
        UsbRomBoot() : BaseRequest(USB_ROM_BOOT) {}
    };
    struct BootApplication : BaseRequest {
        // Common
        BootApplication() : BaseRequest(BOOT_APPLICATION) {}

        // Data
    };

    struct UpdateFlash : BaseRequest {
        // Common
        UpdateFlash() : BaseRequest(UPDATE_FLASH) {}

        // Data
        enum Storage : uint32_t { SBR, BOOTLOADER };
        Storage storage;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct GetBootloaderVersion : BaseRequest {
        // Common
        GetBootloaderVersion() : BaseRequest(GET_BOOTLOADER_VERSION) {}

        // Data
    };

    // 0.0.12 or higher
    struct BootMemory : BaseRequest {
        // Common
        BootMemory() : BaseRequest(BOOT_MEMORY) {}

        // Data
        uint32_t totalSize;
        uint32_t numPackets;
    };

    // UpdateFlashEx - Additional options
    struct UpdateFlashEx : BaseRequest {
        // Common
        UpdateFlashEx() : BaseRequest(UPDATE_FLASH_EX) {}

        // Data
        Memory memory;
        Section section;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    // UpdateFlashEx2 - Additional options
    struct UpdateFlashEx2 : BaseRequest {
        // Common
        UpdateFlashEx2() : BaseRequest(UPDATE_FLASH_EX_2) {}

        // Data
        Memory memory;
        uint32_t offset;
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct GetBootloaderType : BaseRequest {
        // Common
        GetBootloaderType() : BaseRequest(GET_BOOTLOADER_TYPE) {}

        // Data
    };

    // 0.0.14 or higher
    struct SetBootloaderConfig : BaseRequest {
        // Common
        SetBootloaderConfig() : BaseRequest(SET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory = Memory::AUTO;
        int64_t offset = -1;
        uint32_t clearConfig = 0;
        uint32_t totalSize = 0;
        uint32_t numPackets = 0;
    };

    struct GetBootloaderConfig : BaseRequest {
        // Common
        GetBootloaderConfig() : BaseRequest(GET_BOOTLOADER_CONFIG) {}

        // Data
        Memory memory = Memory::AUTO;
        int64_t offset = -1;
    };
    struct BootloaderMemory : BaseRequest {
        // Common
        BootloaderMemory() : BaseRequest(BOOTLOADER_MEMORY) {}

        // Data
    };

}

namespace response {

    enum Command : uint32_t {
        FLASH_COMPLETE = 0,
        FLASH_STATUS_UPDATE,
        BOOTLOADER_VERSION,
        BOOTLOADER_TYPE,
        GET_BOOTLOADER_CONFIG,
        BOOTLOADER_MEMORY,
        BOOT_APPLICATION,
    };

    struct BaseResponse {
        BaseResponse(Command command) : cmd(command){}
        Command cmd;
    };

    // Specific request PODs
    struct FlashComplete : BaseResponse {
        // Common
        FlashComplete() : BaseResponse(FLASH_COMPLETE) {}

        // Data
        uint32_t success;
        char errorMsg[64];
    };
    struct FlashStatusUpdate : BaseResponse {
        // Common
        FlashStatusUpdate() : BaseResponse(FLASH_STATUS_UPDATE) {}

        // Data
        float progress;
    };
    struct BootloaderVersion : BaseResponse {
        // Common
        BootloaderVersion() : BaseResponse(BOOTLOADER_VERSION) {}

        // Data
        uint32_t major, minor, patch;
    };

    struct BootloaderType : BaseResponse {
        // Common
        BootloaderType() : BaseResponse(BOOTLOADER_TYPE) {}

        // Data
        Type type;
    };

    // 0.0.14
    struct GetBootloaderConfig : BaseResponse {
        // Common
        GetBootloaderConfig() : BaseResponse(GET_BOOTLOADER_CONFIG) {}

        // Data
        uint32_t success;
        char errorMsg[64];
        uint32_t totalSize;
        uint32_t numPackets;
    };

    struct BootloaderMemory : BaseResponse {
        // Common
        BootloaderMemory() : BaseResponse(BOOTLOADER_MEMORY) {}

        // Data
        Memory memory;
    };

    struct BootApplication : BaseResponse {
        // Common
        BootApplication() : BaseResponse(BOOT_APPLICATION) {}

        // Data
        uint32_t success;
        char errorMsg[64];
    };
}

} // namespace bootloader
} // namespace dai
<|endoftext|>


<commit_before>#pragma once

#include <tudocomp/Compressor.hpp>

#include <sdsl/cst_fully.hpp>

#include <tudocomp/Range.hpp>
#include <tudocomp/ds/TextDS.hpp>

namespace tdc {

class LZ78UCompressor: public Compressor {
private:
    using cst_t = sdsl::cst_sct3<>;
    using node_type = cst_t::node_type;

    static inline lz78::factorid_t select_size(Env& env, string_ref name) {
        auto& o = env.option(name);
        if (o.as_string() == "inf") {
            return 0;
        } else {
            return o.as_integer();
        }
    }

    /// Max dictionary size before reset
    const lz78::factorid_t m_dict_max_size {0};

public:
    inline LZ78UCompressor(Env&& env):
        Compressor(std::move(env)),
        m_dict_max_size(env.option("dict_size").as_integer())
    {}

    inline static Meta meta() {
        Meta m("compressor", "lz78u", "Lempel-Ziv 78 U\n\n" LZ78_DICT_SIZE_DESC);
        m.option("dict_size").dynamic("inf");
        m.needs_sentinel_terminator();
        return m;
    }

    virtual void compress(Input& input, Output& out) override {
        env().begin_stat_phase("lz78u");

        auto base_view = input.as_view();

        TextDS<> ds { base_view, env(), TextDS<>::ISA };
        auto isa_p = ds.release_isa();
        auto& ISA = *isa_p;

        auto T = base_view.substr(0, base_view.size() - 1);

        cst_t st;
        {
            env().begin_stat_phase("construct suffix tree");

            // TODO: Specialize sdsl template for less alloc here
            std::string bad_copy_1 = T;
            std::cout << vec_to_debug_string(bad_copy_1) << "\n";

            construct_im(st, bad_copy_1, 1);

            env().end_stat_phase();
        }

        std::vector<size_t> R;
        R.reserve(st.nodes());
        R.resize(st.nodes());

        size_t pos = 1;
        size_t parent_pos = 0;
        size_t z = 0;

        auto node = st.root();

        // tx: a a a b a b a a a b a a b a b a $
        // sn:         5         10        15  16

        while (pos <= T.size()) {
            node = st.child(node, T[pos]);

            bool is_leaf = st.is_leaf(node);
            if (is_leaf) {
                std::cout << "pos: " << pos << ", sn: " << st.sn(node) << "\n";
            }

            pos++;

            /*

            size_t node_idx = node;

            if (is_leaf) {
                std::cout << "out l char: " << vec_to_debug_string(T.substr(pos, pos + 1)) << "\n";
                std::cout << "out l idx:  " << 0 << "\n";
                node = st.root();
            } else if(R[node_idx] == 0) {
                z++;
                R[node_idx] = z;
                std::cout << "out m char: " << vec_to_debug_string(T.substr(pos, pos + 1)) << "\n";
                std::cout << "out m idx:  " << 0 << "\n";

            }

            pos += is_leaf ? 1 :*/
        }

        env().end_stat_phase();
    }

    virtual void decompress(Input& input, Output& output) override final {

    }

};

}//ns
<commit_msg>Second revision of paper<commit_after>#pragma once

#include <tudocomp/Compressor.hpp>

#include <sdsl/cst_fully.hpp>
#include <sdsl/cst_sada.hpp>

#include <tudocomp/Range.hpp>
#include <tudocomp/ds/TextDS.hpp>

namespace tdc {

class LZ78UCompressor: public Compressor {
private:
    using cst_t = sdsl::cst_sada<>;
    using node_type = cst_t::node_type;

    static inline lz78::factorid_t select_size(Env& env, string_ref name) {
        auto& o = env.option(name);
        if (o.as_string() == "inf") {
            return 0;
        } else {
            return o.as_integer();
        }
    }

    /// Max dictionary size before reset
    const lz78::factorid_t m_dict_max_size {0};

public:
    inline LZ78UCompressor(Env&& env):
        Compressor(std::move(env)),
        m_dict_max_size(env.option("dict_size").as_integer())
    {}

    inline static Meta meta() {
        Meta m("compressor", "lz78u", "Lempel-Ziv 78 U\n\n" LZ78_DICT_SIZE_DESC);
        m.option("dict_size").dynamic("inf");
        m.needs_sentinel_terminator();
        return m;
    }

    virtual void compress(Input& input, Output& out) override {
        env().begin_stat_phase("lz78u");

        auto T = input.as_view();

        TextDS<> ds { T, env(), TextDS<>::ISA };
        auto isa_p = ds.release_isa();
        auto& ISA = *isa_p;

        cst_t ST;
        {
            env().begin_stat_phase("construct suffix tree");

            // TODO: Specialize sdsl template for less alloc here
            std::string bad_copy_1 = T.substr(0, T.size() - 1);
            std::cout << vec_to_debug_string(bad_copy_1) << "\n";

            construct_im(ST, bad_copy_1, 1);

            env().end_stat_phase();
        }

        std::vector<size_t> R;
        R.reserve(ST.nodes());
        R.resize(ST.nodes());

        size_t pos = 1;
        size_t z = 0;

        // tx: a a a b a b a a a b a a b a b a $
        // sn:         5         10        15  16

        auto lambda = [&ST, &pos, &T](const node_type& l1, const node_type& l2) -> View {
            //auto size1 = ST.depth(l1);
            //auto size2 = ST.depth(l2);
            auto offset1 = T.size() - ST.depth(l1);
            auto offset2 = T.size() - ST.depth(l2);

            std::cout << "pos: " << pos << " lambda: " << offset1 << " vs " << offset2 << "\n";

            //auto offset1 = ST.sn(l1);
            //auto offset2 = ST.sn(l2);

            if (offset1 < offset2) {
                return T.substr(offset1, offset2);
            } else {
                throw std::runtime_error("asdf");
            }
        };

        auto parent = [&ST](const node_type& n) {
            return ST.parent(n);
        };

        auto leaf_select = [&ST](const size_t& pos) {
            return ST.select_leaf(pos);
        };

        auto level_anc = [&ST](const node_type& n, size_t d) {
            return ST.sl(n, d);
        };

        while (pos <= T.size()) {
            auto l = leaf_select(ISA[pos]);

            if (R[parent(l)] != 0) {
                std::cout << "out l c: " << int(lambda(parent(l), l)[0]) << "\n";
                std::cout << "out l r: " << int(0) << "\n";
                pos++;
            } else {
                size_t d = 1;
                while (level_anc(l, d) != 0) {
                    d++;
                    pos += lambda(level_anc(l, d - 1), level_anc(l, d)).size();
                }
                auto node = level_anc(l, d);
                z++;
                R[node] = z;

                std::cout << "out m s: " << vec_to_debug_string(lambda(parent(node), node)) << "\n";
                std::cout << "out m r: " << int(R[parent(node)]) << "\n";
                pos += lambda(parent(node), node).size();
            }
        }

        env().end_stat_phase();
    }

    virtual void decompress(Input& input, Output& output) override final {

    }

};

}//ns
<|endoftext|>


<commit_before>#pragma once
#include <numeric>
#include <type_traits>
#include <utility>
#include <functional>
#include <string>
#include <cstring>
#include <cassert>
#include <tuple>
#include <vector>
#include <optional>
#include <variant>

namespace bw
{
	template<typename T> constexpr int EnumCount = 0;
	template<typename T, typename = void> struct Type;

	struct Reader
	{
		Reader(const char* from, const char* to) : from(from), to(to) {}
		Reader(const std::vector<char>& src) : from(src.data()), to(src.data() + src.size()) {}

		size_t size() const { return to - from; }

		void read(void* dest, size_t len)
		{
			if(len > size()) throw std::range_error("Insufficient bytes in range");
			memcpy(dest, from, len);
			from += len;
		}

		uint32_t readBits(uint8_t count)
		{
			uint32_t result = 0;
			uint8_t pos = 0;
			while(count)
			{
				if(!bitsLeft)
				{
					read(&bits, 1);
					bitsLeft = 8;
				}
				uint8_t bitsToRead = std::min(bitsLeft, count);
				uint8_t mask = (uint32_t(1) << bitsToRead) - 1;
				result |= (mask & bits) << pos;
				pos += bitsToRead;
				count -= bitsToRead;
				bitsLeft -= bitsToRead;
				bits >>= bitsToRead;
			}
			return result;
		}

		template<typename T> auto unpack() { return Type<std::decay_t<T>>::unpack(*this); }

	private:
		const char* from;
		const char* to;
		uint8_t bits;
		uint8_t bitsLeft = 0;
	};

	struct Writer
	{
		Writer(std::vector<char>& dest) : dest(dest) {}

		void write(const void* src, size_t len)
		{
			dest.insert(dest.end(), (const char*)src, (const char*)src + len);
		}

		void writeBits(uint32_t bits, uint8_t count)
		{
			while(count)
			{
				if(!bitsLeft)
				{
					bitsPos = dest.size();
					dest.push_back(0);
					bitsLeft = 8;
				}
				uint8_t bitsToWrite = std::min(bitsLeft, count);
				uint8_t mask = (uint32_t(1) << bitsToWrite) - 1;
				dest[bitsPos] |= (mask & bits) << (8 - bitsLeft);
				bitsLeft -= bitsToWrite;
				count -= bitsToWrite;
				bits >>= bitsToWrite;
			}
		}

		template<typename T> void pack(const T& x) { Type<std::decay_t<T>>::packInto(*this, x); }

	private:
		std::vector<char>& dest;
		size_t bitsPos;
		uint8_t bitsLeft = 0;
	};

	constexpr uint8_t bitsNeeded(size_t max) { return 32 - __builtin_clz(max); }
	template<typename T> std::string toString(const T& x) { return Type<std::decay_t<T>>::toString(x); }
	template<typename T> constexpr size_t bitLength(const T& x) { return Type<std::decay_t<T>>::bitLength(x); }
	template<typename T> constexpr size_t byteLength(const T& x) { return (bitLength(x) + 7)/8; }
	template<typename T> T unpack(const std::vector<char>& buf) { return Reader(buf).unpack<T>(); }

	template<typename T> std::vector<char> pack(const T& x)
	{
		std::vector<char> r;
		r.reserve(byteLength(x));
		Writer(r).pack(x);
		return r;
	}

	inline float asFloat(uint32_t x) { float f; memcpy(&f, &x, sizeof(x)); return f; }
	inline float scale(float v, float vmin, float vmax, float min, float max) { return (v - vmin)/(vmax - vmin)*(max - min) + min; }

	template<typename U, uint32_t Min, uint32_t Max> struct Scaled
	{
		U value;
		Scaled() {}
		Scaled(float v) { *this = v; }
		explicit Scaled(U value) : value(value) {}
		static float min() { return asFloat(Min); }
		static float max() { return asFloat(Max); }
		operator float() const { return scale(value, std::numeric_limits<U>::min(), std::numeric_limits<U>::max(), min(), max()); }
		auto& operator=(float v) { value = scale(v, min(), max(), std::numeric_limits<U>::min(), std::numeric_limits<U>::max()); return *this; }
	};

	template<typename T, typename> struct Type
	{
		static std::string toString(const T& x) { return bw::toString(~x); }
		static constexpr size_t bitLength(const T& x) { return bw::bitLength(~x); }
		static T unpack(Reader& r) { return Type<decltype(~std::declval<T>())>::template unpackAs<T>(r); }
		static void packInto(Writer& w, const T& x) { w.pack(~x); }
	};

	template<typename U, uint32_t Min, uint32_t Max> struct Type<Scaled<U, Min, Max>>
	{
		using T = Scaled<U, Min, Max>;
		static std::string toString(const T& x) { return std::to_string((float)x); }
		static constexpr size_t bitLength(const T& x) { return bw::bitLength(x.value); }
		static T unpack(Reader& r) { return T(r.unpack<U>()); }
		static void packInto(Writer& w, const T& x) { w.pack<U>(x.value); }
	};

	template<> struct Type<bool>
	{
		static std::string toString(const bool& x) { return x ? "+" : "-"; }
		static constexpr size_t bitLength(const bool&) { return 1; }
		static bool unpack(Reader& r) { return r.readBits(1); }
		static void packInto(Writer& w, const bool& x) { w.writeBits(x, 1); }
	};

	template<typename T> struct Type<T, std::enable_if_t<std::is_enum_v<T>, void>>
	{
		static constexpr uint8_t bits = bitsNeeded(EnumCount<T> - 1);
		static std::string toString(const T& x) { return std::to_string((uint8_t)x); }
		static constexpr size_t bitLength(const T&) { return bits; }
		static T unpack(Reader& r) { return (T)r.readBits(bits); }
		static void packInto(Writer& w, const T& x) { w.writeBits((uint32_t)x, bits); }
	};

	template<typename T> struct Type<T, std::enable_if_t<std::is_arithmetic_v<T>, void>>
	{
		static std::string toString(const T& x) { return std::to_string(x); }
		static constexpr size_t bitLength(const T&) { return 8*sizeof(T); }
		static T unpack(Reader& r) { T x; r.read(&x, sizeof(T)); return x; }
		static void packInto(Writer& w, const T& x) { w.write(&x, sizeof(T)); }
	};

	namespace varint
	{
		static constexpr uint8_t bytesBitsNeeded(size_t v) { return v <= 0xffff ? (v <= 0xff ? 0 : 1) : (v <= 0xffffffff ? 2 : 3); }
		static constexpr size_t bitLength(size_t x) { return 2 + 8*(size_t(1) << bytesBitsNeeded(x)); }

		static size_t unpack(Reader& r)
		{
			switch(r.readBits(2))
			{
				case 0: return r.unpack<uint8_t>();
				case 1: return r.unpack<uint16_t>();
				case 2: return r.unpack<uint32_t>();
			}
			return r.unpack<uint64_t>();
		}

		static void packInto(Writer& w, size_t x)
		{
			uint8_t bb = bytesBitsNeeded(x);
			w.writeBits(bb, 2);
			switch(bb)
			{
				case 0: return Type<uint8_t>::packInto(w, x);
				case 1: return Type<uint16_t>::packInto(w, x);
				case 2: return Type<uint32_t>::packInto(w, x);
				case 3: return Type<uint64_t>::packInto(w, x);
			}
		}
	};

	template<> struct Type<std::string>
	{
		static std::string toString(const std::string& x) { return '\'' + x + '\''; }
		static size_t bitLength(const std::string& x) { return varint::bitLength(x.size()) + 8*x.size(); }

		static std::string unpack(Reader& r)
		{
			size_t len = varint::unpack(r);
			std::string x;
			char s[1024];
			while(len)
			{
				size_t n = std::min(len, sizeof(s));
				r.read(s, n);
				x.insert(x.end(), s, s + n);
				len -= n;
			}
			return x;
		}

		static void packInto(Writer& w, const std::string& x)
		{
			varint::packInto(w, x.size());
			w.write(x.data(), x.size());
		}
	};

	template<typename T> struct Type<std::optional<T>>
	{
		static std::string toString(const std::optional<T>& x) { return x ? bw::toString(*x) : "?"; }
		static constexpr size_t bitLength(const std::optional<T>& x) { return 1 + (x ? bw::bitLength(*x) : 0); }
		static std::optional<T> unpack(Reader& r) { return r.readBits(1) ? std::optional(r.unpack<T>()) : std::nullopt; }

		static void packInto(Writer& w, const std::optional<T>& x)
		{
			w.writeBits(bool(x), 1);
			if(x) w.pack(*x);
		}
	};

	template<typename T> struct Type<std::vector<T>>
	{
		static std::string toString(const std::vector<T>& x)
		{
			std::string result = "[ ";
			for(const auto& m : x) result += bw::toString(m) += ' ';
			return result += ']';
		}

		static size_t bitLength(const std::vector<T>& x)
		{
			size_t s = varint::bitLength(x.size());
			for(const T& m : x) s += bw::bitLength(m);
			return s;
		}

		static std::vector<T> unpack(Reader& r)
		{
			size_t len = varint::unpack(r);
			std::vector<T> x;
			while(len--) x.push_back(r.unpack<T>());
			return x;
		}

		static void packInto(Writer& w, const std::vector<T>& x)
		{
			varint::packInto(w, x.size());
			for(const auto& v : x) w.pack(v);
		}
	};

	template<typename... Args> struct Type<std::tuple<Args...>>
	{
		static std::string toString(const std::tuple<Args...>& x) { return std::apply([](const auto&... args) { return "( " + ((bw::toString(args) + ' ') + ...) + ')'; }, x); }
		static constexpr size_t bitLength(const std::tuple<Args...>& x) { return std::apply([](const auto&... args) { return (bw::bitLength(args) + ...); }, x); }
		template<typename T> static T unpackAs(Reader& r) { return T{r.unpack<Args>()...}; }
		static auto unpack(Reader& r) { return unpackAs<std::tuple<std::decay_t<Args>...>>(r); }
		static void packInto(Writer& w, const std::tuple<Args...>& x) { std::apply([&](const auto&... args) { (w.pack(args), ...); }, x); }
	};
}
<commit_msg>String view support<commit_after>#pragma once
#include <numeric>
#include <type_traits>
#include <utility>
#include <functional>
#include <string>
#include <cstring>
#include <cassert>
#include <tuple>
#include <vector>
#include <optional>
#include <variant>

namespace bw
{
	template<typename T> constexpr int EnumCount = 0;
	template<typename T, typename = void> struct Type;

	struct Reader
	{
		Reader(const char* from, const char* to) : from(from), to(to) {}
		Reader(std::string_view src) : from(src.data()), to(src.data() + src.size()) {}
		Reader(const std::vector<char>& src) : from(src.data()), to(src.data() + src.size()) {}

		size_t size() const { return to - from; }

		void read(void* dest, size_t len)
		{
			if(len > size()) throw std::range_error("Insufficient bytes in range");
			memcpy(dest, from, len);
			from += len;
		}

		uint32_t readBits(uint8_t count)
		{
			uint32_t result = 0;
			uint8_t pos = 0;
			while(count)
			{
				if(!bitsLeft)
				{
					read(&bits, 1);
					bitsLeft = 8;
				}
				uint8_t bitsToRead = std::min(bitsLeft, count);
				uint8_t mask = (uint32_t(1) << bitsToRead) - 1;
				result |= (mask & bits) << pos;
				pos += bitsToRead;
				count -= bitsToRead;
				bitsLeft -= bitsToRead;
				bits >>= bitsToRead;
			}
			return result;
		}

		template<typename T> auto unpack() { return Type<std::decay_t<T>>::unpack(*this); }

	private:
		const char* from;
		const char* to;
		uint8_t bits;
		uint8_t bitsLeft = 0;
	};

	struct Writer
	{
		Writer(std::vector<char>& dest) : dest(dest) {}

		void write(const void* src, size_t len)
		{
			dest.insert(dest.end(), (const char*)src, (const char*)src + len);
		}

		void writeBits(uint32_t bits, uint8_t count)
		{
			while(count)
			{
				if(!bitsLeft)
				{
					bitsPos = dest.size();
					dest.push_back(0);
					bitsLeft = 8;
				}
				uint8_t bitsToWrite = std::min(bitsLeft, count);
				uint8_t mask = (uint32_t(1) << bitsToWrite) - 1;
				dest[bitsPos] |= (mask & bits) << (8 - bitsLeft);
				bitsLeft -= bitsToWrite;
				count -= bitsToWrite;
				bits >>= bitsToWrite;
			}
		}

		template<typename T> void pack(const T& x) { Type<std::decay_t<T>>::packInto(*this, x); }

	private:
		std::vector<char>& dest;
		size_t bitsPos;
		uint8_t bitsLeft = 0;
	};

	constexpr uint8_t bitsNeeded(size_t max) { return 32 - __builtin_clz(max); }
	template<typename T> std::string toString(const T& x) { return Type<std::decay_t<T>>::toString(x); }
	template<typename T> constexpr size_t bitLength(const T& x) { return Type<std::decay_t<T>>::bitLength(x); }
	template<typename T> constexpr size_t byteLength(const T& x) { return (bitLength(x) + 7)/8; }
	template<typename T> T unpack(const std::vector<char>& buf) { return Reader(buf).unpack<T>(); }

	template<typename T> std::vector<char> pack(const T& x)
	{
		std::vector<char> r;
		r.reserve(byteLength(x));
		Writer(r).pack(x);
		return r;
	}

	inline float asFloat(uint32_t x) { float f; memcpy(&f, &x, sizeof(x)); return f; }
	inline float scale(float v, float vmin, float vmax, float min, float max) { return (v - vmin)/(vmax - vmin)*(max - min) + min; }

	template<typename U, uint32_t Min, uint32_t Max> struct Scaled
	{
		U value;
		Scaled() {}
		Scaled(float v) { *this = v; }
		explicit Scaled(U value) : value(value) {}
		static float min() { return asFloat(Min); }
		static float max() { return asFloat(Max); }
		operator float() const { return scale(value, std::numeric_limits<U>::min(), std::numeric_limits<U>::max(), min(), max()); }
		auto& operator=(float v) { value = scale(v, min(), max(), std::numeric_limits<U>::min(), std::numeric_limits<U>::max()); return *this; }
	};

	template<typename T, typename> struct Type
	{
		static std::string toString(const T& x) { return bw::toString(~x); }
		static constexpr size_t bitLength(const T& x) { return bw::bitLength(~x); }
		static T unpack(Reader& r) { return Type<decltype(~std::declval<T>())>::template unpackAs<T>(r); }
		static void packInto(Writer& w, const T& x) { w.pack(~x); }
	};

	template<typename U, uint32_t Min, uint32_t Max> struct Type<Scaled<U, Min, Max>>
	{
		using T = Scaled<U, Min, Max>;
		static std::string toString(const T& x) { return std::to_string((float)x); }
		static constexpr size_t bitLength(const T& x) { return bw::bitLength(x.value); }
		static T unpack(Reader& r) { return T(r.unpack<U>()); }
		static void packInto(Writer& w, const T& x) { w.pack<U>(x.value); }
	};

	template<> struct Type<bool>
	{
		static std::string toString(const bool& x) { return x ? "+" : "-"; }
		static constexpr size_t bitLength(const bool&) { return 1; }
		static bool unpack(Reader& r) { return r.readBits(1); }
		static void packInto(Writer& w, const bool& x) { w.writeBits(x, 1); }
	};

	template<typename T> struct Type<T, std::enable_if_t<std::is_enum_v<T>, void>>
	{
		static constexpr uint8_t bits = bitsNeeded(EnumCount<T> - 1);
		static std::string toString(const T& x) { return std::to_string((uint8_t)x); }
		static constexpr size_t bitLength(const T&) { return bits; }
		static T unpack(Reader& r) { return (T)r.readBits(bits); }
		static void packInto(Writer& w, const T& x) { w.writeBits((uint32_t)x, bits); }
	};

	template<typename T> struct Type<T, std::enable_if_t<std::is_arithmetic_v<T>, void>>
	{
		static std::string toString(const T& x) { return std::to_string(x); }
		static constexpr size_t bitLength(const T&) { return 8*sizeof(T); }
		static T unpack(Reader& r) { T x; r.read(&x, sizeof(T)); return x; }
		static void packInto(Writer& w, const T& x) { w.write(&x, sizeof(T)); }
	};

	namespace varint
	{
		static constexpr uint8_t bytesBitsNeeded(size_t v) { return v <= 0xffff ? (v <= 0xff ? 0 : 1) : (v <= 0xffffffff ? 2 : 3); }
		static constexpr size_t bitLength(size_t x) { return 2 + 8*(size_t(1) << bytesBitsNeeded(x)); }

		static size_t unpack(Reader& r)
		{
			switch(r.readBits(2))
			{
				case 0: return r.unpack<uint8_t>();
				case 1: return r.unpack<uint16_t>();
				case 2: return r.unpack<uint32_t>();
			}
			return r.unpack<uint64_t>();
		}

		static void packInto(Writer& w, size_t x)
		{
			uint8_t bb = bytesBitsNeeded(x);
			w.writeBits(bb, 2);
			switch(bb)
			{
				case 0: return Type<uint8_t>::packInto(w, x);
				case 1: return Type<uint16_t>::packInto(w, x);
				case 2: return Type<uint32_t>::packInto(w, x);
				case 3: return Type<uint64_t>::packInto(w, x);
			}
		}
	};

	template<> struct Type<std::string>
	{
		static std::string toString(const std::string& x) { return '\'' + x + '\''; }
		static size_t bitLength(const std::string& x) { return varint::bitLength(x.size()) + 8*x.size(); }

		static std::string unpack(Reader& r)
		{
			size_t len = varint::unpack(r);
			std::string x;
			char s[1024];
			while(len)
			{
				size_t n = std::min(len, sizeof(s));
				r.read(s, n);
				x.insert(x.end(), s, s + n);
				len -= n;
			}
			return x;
		}

		static void packInto(Writer& w, const std::string& x)
		{
			varint::packInto(w, x.size());
			w.write(x.data(), x.size());
		}
	};

	template<typename T> struct Type<std::optional<T>>
	{
		static std::string toString(const std::optional<T>& x) { return x ? bw::toString(*x) : "?"; }
		static constexpr size_t bitLength(const std::optional<T>& x) { return 1 + (x ? bw::bitLength(*x) : 0); }
		static std::optional<T> unpack(Reader& r) { return r.readBits(1) ? std::optional(r.unpack<T>()) : std::nullopt; }

		static void packInto(Writer& w, const std::optional<T>& x)
		{
			w.writeBits(bool(x), 1);
			if(x) w.pack(*x);
		}
	};

	template<typename T> struct Type<std::vector<T>>
	{
		static std::string toString(const std::vector<T>& x)
		{
			std::string result = "[ ";
			for(const auto& m : x) result += bw::toString(m) += ' ';
			return result += ']';
		}

		static size_t bitLength(const std::vector<T>& x)
		{
			size_t s = varint::bitLength(x.size());
			for(const T& m : x) s += bw::bitLength(m);
			return s;
		}

		static std::vector<T> unpack(Reader& r)
		{
			size_t len = varint::unpack(r);
			std::vector<T> x;
			while(len--) x.push_back(r.unpack<T>());
			return x;
		}

		static void packInto(Writer& w, const std::vector<T>& x)
		{
			varint::packInto(w, x.size());
			for(const auto& v : x) w.pack(v);
		}
	};

	template<typename... Args> struct Type<std::tuple<Args...>>
	{
		static std::string toString(const std::tuple<Args...>& x) { return std::apply([](const auto&... args) { return "( " + ((bw::toString(args) + ' ') + ...) + ')'; }, x); }
		static constexpr size_t bitLength(const std::tuple<Args...>& x) { return std::apply([](const auto&... args) { return (bw::bitLength(args) + ...); }, x); }
		template<typename T> static T unpackAs(Reader& r) { return T{r.unpack<Args>()...}; }
		static auto unpack(Reader& r) { return unpackAs<std::tuple<std::decay_t<Args>...>>(r); }
		static void packInto(Writer& w, const std::tuple<Args...>& x) { std::apply([&](const auto&... args) { (w.pack(args), ...); }, x); }
	};
}
<|endoftext|>


<commit_before>#pragma once

#include <iostream>

#include "binary.hxx"
#include "bitnode.hxx"

namespace despairagus {
	namespace bitwisetrie {
		using std::cout;
		using std::ostream;
		using namespace bitnodeNS;
		using namespace binaryNS;

		template <typename A, typename B>
		class bitwisetrie final {
			template<typename C>
			using conref = const C&;

			using bitA = std::bitset<sizeof(A) << 3>;
			using byte = unsigned char;
			using bit = bool;

			constexpr static const size_t limit{sizeof(A) << 3};

			static inline bitnode<B>* navigate(bitnode<B>* currNode, conref<A> data) {
				return bitwisetrie<A,B>::navigate(currNode, data, 0);
			}

			static inline bitnode<B>* navigate(bitnode<B>* currNode, conref<A> data, conref<size_t> idx) {
				binary<A> bitHolder{data};

				return bitwisetrie<A,B>::navigate(currNode, bitHolder, idx);
			}

			static bitnode<B>* navigate(bitnode<B>* currNode, conref<binary<A>> bits, conref<size_t> idx) {
				if (idx < limit) {
					if (bits.getBit(idx)) {
						if (currNode->getOne() == nullptr) {
							currNode->setOne(new bitnode<B>);
						}

						return bitwisetrie<A,B>::navigate(currNode->getOne(), bits, idx + 1);
					} else {
						if (currNode->getZero() == nullptr) {
							currNode->setZero(new bitnode<B>);
						}

						return bitwisetrie<A,B>::navigate(currNode->getZero(), bits, idx + 1);
					}
				}

				return currNode;
			}

		public:
			explicit bitwisetrie(void) : root{new bitnode<B>} {}

			inline bool insertOnEmpty(conref<A> a, conref<B> b) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				if (leafNode->isEmpty()) {
					leafNode->setData(b);

					return true;
				}

				return false;
			}

			inline bool insertOnNotEmpty(conref<A> a, conref<B> b) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				if (leafNode->isNotEmpty()) {
					leafNode->setData(b);

					return true;
				}

				return false;
			}

			inline void insert(conref<A> a, conref<B> b) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				leafNode->setData(a);
			}

			inline bool remove(conref<A> a) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				if (leafNode->isNotEmpty()) {
					leafNode->dump();

					return true;
				}

				return false;
			}

			inline bool contains(conref<A> a) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				return leafNode->isNotEmpty();
			}

			inline bool notContains(conref<A> a) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				return leafNode->isEmpty();
			}

		private:
			bitnode<B>* root;
		};
	}
}
<commit_msg>compiler doesn't like it when namespace and class share name<commit_after>#pragma once

#include <iostream>

#include "binary.hxx"
#include "bitnode.hxx"

namespace despairagus {
	namespace bitwisetrieNS {
		using std::cout;
		using std::ostream;
		using namespace bitnodeNS;
		using namespace binaryNS;

		template <typename A, typename B>
		class bitwisetrie final {
			template<typename C>
			using conref = const C&;

			using bitA = std::bitset<sizeof(A) << 3>;
			using byte = unsigned char;
			using bit = bool;

			constexpr static const size_t limit{sizeof(A) << 3};

			static inline bitnode<B>* navigate(bitnode<B>* currNode, conref<A> data) {
				return bitwisetrie<A,B>::navigate(currNode, data, 0);
			}

			static inline bitnode<B>* navigate(bitnode<B>* currNode, conref<A> data, conref<size_t> idx) {
				binary<A> bitHolder{data};

				return bitwisetrie<A,B>::navigate(currNode, bitHolder, idx);
			}

			static bitnode<B>* navigate(bitnode<B>* currNode, conref<binary<A>> bits, conref<size_t> idx) {
				if (idx < limit) {
					if (bits.getBit(idx)) {
						if (currNode->getOne() == nullptr) {
							currNode->setOne(new bitnode<B>);
						}

						return bitwisetrie<A,B>::navigate(currNode->getOne(), bits, idx + 1);
					} else {
						if (currNode->getZero() == nullptr) {
							currNode->setZero(new bitnode<B>);
						}

						return bitwisetrie<A,B>::navigate(currNode->getZero(), bits, idx + 1);
					}
				}

				return currNode;
			}

		public:
			explicit bitwisetrie(void) : root{new bitnode<B>} {}

			inline bool insertOnEmpty(conref<A> a, conref<B> b) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				if (leafNode->isEmpty()) {
					leafNode->setData(b);

					return true;
				}

				return false;
			}

			inline bool insertOnNotEmpty(conref<A> a, conref<B> b) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				if (leafNode->isNotEmpty()) {
					leafNode->setData(b);

					return true;
				}

				return false;
			}

			inline void insert(conref<A> a, conref<B> b) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				leafNode->setData(a);
			}

			inline bool remove(conref<A> a) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				if (leafNode->isNotEmpty()) {
					leafNode->dump();

					return true;
				}

				return false;
			}

			inline bool contains(conref<A> a) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				return leafNode->isNotEmpty();
			}

			inline bool notContains(conref<A> a) noexcept {
				bitnode<B>* leafNode = bitwisetrie<A,B>::navigate(root, a);

				return leafNode->isEmpty();
			}

		private:
			bitnode<B>* root;
		};
	}
}
<|endoftext|>


<commit_before>#include "isinst.h"
#include "values32b.h"
#include <cstdint>

#include "NodeDeepChecksum.h"
#include "brawlprintf.h"

using namespace System;
using System::ComponentModel::CategoryAttribute;
using System::Reflection::PropertyInfo;
using System::Text::StringBuilder;
using System::IO::StringWriter;
using namespace BrawlLib::SSBB::ResourceNodes;

bool data_tag_is(const char* tag, ResourceNode^ node) {
	if (node->UncompressedSource.Length < 4) return false;
	char* ptr = (char*)(void*)node->UncompressedSource.Address;
	for (int i = 0; i < 4; i++) {
		if (ptr[i] != tag[i]) return false;
	}
	return true;
}

String^ format_obj(String^ format, String^ prefix, Object^ obj) {
	String^ name = obj == nullptr
		? "null"
		: obj->ToString();
	String^ bone = "";
	if (isinst<MDL0BoneNode^>(obj)) {
		MDL0BoneNode^ b = (MDL0BoneNode^)obj;
		bone = "T" + b->Translation;
		bone += " R" + b->Rotation;
		bone += " S" + b->Scale;
	}
	String^ index = "";
	String^ md5 = "";
	String^ size = "";
	String^ path = "";
	if (isinst<ResourceNode^>(obj)) {
		ResourceNode^ node = (ResourceNode^)obj;
		if (format->Contains("%m")) { // don't do this if we don't need the data - this does save some time
			md5 = "MD5:" + MD5EnsureChildrenIncluded(node, nullptr);
		}
		index = node->Index + "";
		size = node->OriginalSource.Length + "";
		while (node->Parent != nullptr) {
			path = node->Name + "/" + path;
			node = node->Parent;
		}
		if (path->EndsWith("/")) path = path->Substring(0, path->Length - 1);
	}

	StringBuilder name2;
	for each (wchar_t c in name) {
		if (c > 128) {
			name2.Append("\\u" + ((int)c).ToString("x4"));
		} else {
			name2.Append(c);
		}
	}
	name = name2.ToString();

	return format
		->Replace("%~", prefix)
		->Replace("%n", name)
		->Replace("%p", path)
		->Replace("%i", index)
		->Replace("%t", "(" + obj->GetType()->Name + ")")
		->Replace("%b", bone)
		->Replace("%m", md5)
		->Replace("%s", size)
		->Replace("%%", "%");
}

String^ properties_lines(String^ prefix, Object^ node) {
	StringBuilder sb;
	for each(PropertyInfo^ entry in node->GetType()->GetProperties()) {
		for each(Attribute^ attribute in entry->GetCustomAttributes(false)) {
			if (isinst<CategoryAttribute^>(attribute)) {
				Object^ val = entry->GetValue(node, nullptr);
				String^ valstr = val == nullptr
					? "null"
					: val->ToString();
				sb.AppendLine(prefix + entry->Name + " " + valstr);
			}
		}
	}
	return sb.ToString();
}

String^ stdt_lines(String^ prefix, STDTNode^ node) {
	StringBuilder sb;
	for each(AttributeInterpretation^ ai in node->GetPossibleInterpretations()) {
		array<AttributeInfo^>^ arr = ai->Array;
		for (int i = 0; i < arr->Length; i++) {
			sb.Append(prefix + arr[i]->_name + " ");
			sb.AppendLine(arr[i]->_type == 0 ? node->GetFloat(i).ToString()
				: arr[i]->_type == 1 ? node->GetInt(i).ToString()
				: "x" + node->GetInt(i).ToString("X8"));
		}
		break;
	}
	return sb.ToString();
}

String^ details_str(String^ prefix, ResourceNode^ node) {
	if (isinst<STPMEntryNode^>(node)) {
		return properties_lines(prefix, node);
	} else if (isinst<MSBinNode^>(node)) {
		MSBinNode^ msbin = (MSBinNode^)node;
		StringBuilder sb;
		for each(String^ s in msbin->_strings) {
			sb.AppendLine(prefix + s);
		}
		return sb.ToString();
	} else if (isinst<STDTNode^>(node)) {
		return stdt_lines(prefix, (STDTNode^)node);
	} else {
		return nullptr;
	}
}
<commit_msg>Fix printing of checksums<commit_after>#include "isinst.h"
#include "values32b.h"
#include <cstdint>

#include "NodeDeepChecksum.h"
#include "brawlprintf.h"

using namespace System;
using System::ComponentModel::CategoryAttribute;
using System::Reflection::PropertyInfo;
using System::Text::StringBuilder;
using System::IO::StringWriter;
using namespace BrawlLib::SSBB::ResourceNodes;

bool data_tag_is(const char* tag, ResourceNode^ node) {
	if (node->UncompressedSource.Length < 4) return false;
	char* ptr = (char*)(void*)node->UncompressedSource.Address;
	for (int i = 0; i < 4; i++) {
		if (ptr[i] != tag[i]) return false;
	}
	return true;
}

String^ format_obj(String^ format, String^ prefix, Object^ obj) {
	String^ name = obj == nullptr
		? "null"
		: obj->ToString();
	String^ bone = "";
	if (isinst<MDL0BoneNode^>(obj)) {
		MDL0BoneNode^ b = (MDL0BoneNode^)obj;
		bone = "T" + b->Translation;
		bone += " R" + b->Rotation;
		bone += " S" + b->Scale;
	}
	String^ index = "";
	String^ md5 = "";
	String^ size = "";
	String^ path = "";
	if (isinst<ResourceNode^>(obj)) {
		ResourceNode^ node = (ResourceNode^)obj;
		if (format->Contains("%m")) { // don't do this if we don't need the data - this does save some time
			md5 = "MD5:";
			for each (unsigned char c in MD5EnsureChildrenIncluded(node, nullptr)) {
				md5 += c.ToString("X2");
			}
		}
		index = node->Index + "";
		size = node->OriginalSource.Length + "";
		while (node->Parent != nullptr) {
			path = node->Name + "/" + path;
			node = node->Parent;
		}
		if (path->EndsWith("/")) path = path->Substring(0, path->Length - 1);
	}

	StringBuilder name2;
	for each (wchar_t c in name) {
		if (c > 128) {
			name2.Append("\\u" + ((int)c).ToString("x4"));
		} else {
			name2.Append(c);
		}
	}
	name = name2.ToString();

	return format
		->Replace("%~", prefix)
		->Replace("%n", name)
		->Replace("%p", path)
		->Replace("%i", index)
		->Replace("%t", "(" + obj->GetType()->Name + ")")
		->Replace("%b", bone)
		->Replace("%m", md5)
		->Replace("%s", size)
		->Replace("%%", "%");
}

String^ properties_lines(String^ prefix, Object^ node) {
	StringBuilder sb;
	for each(PropertyInfo^ entry in node->GetType()->GetProperties()) {
		for each(Attribute^ attribute in entry->GetCustomAttributes(false)) {
			if (isinst<CategoryAttribute^>(attribute)) {
				Object^ val = entry->GetValue(node, nullptr);
				String^ valstr = val == nullptr
					? "null"
					: val->ToString();
				sb.AppendLine(prefix + entry->Name + " " + valstr);
			}
		}
	}
	return sb.ToString();
}

String^ stdt_lines(String^ prefix, STDTNode^ node) {
	StringBuilder sb;
	for each(AttributeInterpretation^ ai in node->GetPossibleInterpretations()) {
		array<AttributeInfo^>^ arr = ai->Array;
		for (int i = 0; i < arr->Length; i++) {
			sb.Append(prefix + arr[i]->_name + " ");
			sb.AppendLine(arr[i]->_type == 0 ? node->GetFloat(i).ToString()
				: arr[i]->_type == 1 ? node->GetInt(i).ToString()
				: "x" + node->GetInt(i).ToString("X8"));
		}
		break;
	}
	return sb.ToString();
}

String^ details_str(String^ prefix, ResourceNode^ node) {
	if (isinst<STPMEntryNode^>(node)) {
		return properties_lines(prefix, node);
	} else if (isinst<MSBinNode^>(node)) {
		MSBinNode^ msbin = (MSBinNode^)node;
		StringBuilder sb;
		for each(String^ s in msbin->_strings) {
			sb.AppendLine(prefix + s);
		}
		return sb.ToString();
	} else if (isinst<STDTNode^>(node)) {
		return stdt_lines(prefix, (STDTNode^)node);
	} else {
		return nullptr;
	}
}
<|endoftext|>


<commit_before>
#define ArduinoDue
#include "ADS1298.h"

// set up the speed, data order and data mode
//SPISettings settingsADS1298(_CLOCK, _BITORDER, _DATAMODE);

//ADS Initialitation
void ADS1298::initialize(byte SampleRate, byte ADSNum, byte ChipSelect)
{

	_NUMBEROFADS = (int)ADSNum;
	ADS_SS = (int)ChipSelect;

	//Initialize the SPI communication
	SPI.begin(ADS_SS);
	SPI.setClockDivider(ADS_SS, 21);
	SPI.setDataMode(ADS_SS, _DATAMODE);
	SPI.setBitOrder(ADS_SS, _BITORDER);

	delay(50);

	//SPI Reset
	SPI.transfer(ADS_SS, _RESET);

	delayMicroseconds(12);    	//must wait 18 tCLK cycles to execute this command

	SPI.transfer(ADS_SS, _SDATAC, SPI_CONTINUE);		//stop read data so registers can be written… 0x11
	delayMicroseconds(3);   	//must wait 4 tCLK cycles after executing this command

	SPI.transfer(ADS_SS, CONFIG1 | _WREG, SPI_CONTINUE);	//Write Regs from REG1 to REG4… 0x41
	SPI.transfer(ADS_SS, 0x02, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_HIGHRESOLUTION | ADS_DAISYCHAIN | ADS_CLK_OUTENABLE | SampleRate, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_WCT_CHOP | ADS_INT_TEST_INT | ADS_TEST_AMP_2 | ADS_TEST_FREQ_1SEC, SPI_CONTINUE);	  //Test signal intern, 0x30 := –1 × (VREFP – VREFN)/2.4mV, 0x34 := –2 × (VREFP – VREFN)/2.4mV
	SPI.transfer(ADS_SS, ADS_PDB_REFBUF_ON | ADS_VREFP_2_4 | ADS_OPAMP_REF_PIN | ADS_PDB_OPAMP_PD);		//Internal reference

	delay(1);

}

// to be sure that all the ADCs are configured
void ADS1298::reINITforMoreADC(byte SampleRate, byte ModeADS)
{

	SPI.transfer(ADS_SS, CONFIG1 | _WREG, SPI_CONTINUE);	//Write Regs from REG1 to REG4… 0x41
	SPI.transfer(ADS_SS, 0x02, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_HIGHRESOLUTION | ADS_DAISYCHAIN | ADS_CLK_OUTENABLE | SampleRate, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_WCT_CHOP | ADS_INT_TEST_INT | ADS_TEST_AMP_2 | ADS_TEST_FREQ_1SEC, SPI_CONTINUE);	  //Test signal intern, 0x30 := –1 × (VREFP – VREFN)/2.4mV, 0x34 := –2 × (VREFP – VREFN)/2.4mV
	SPI.transfer(ADS_SS, ADS_PDB_REFBUF_ON | ADS_VREFP_2_4 | ADS_OPAMP_REF_PIN | ADS_PDB_OPAMP_PD, SPI_CONTINUE);		//Internal reference

	delay(1);

	SPI.transfer(ADS_SS, CH1SET | _WREG, SPI_CONTINUE);	//Write Regs from REG5 to REG13… 0x45
	SPI.transfer(ADS_SS, 0x07, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);		//CH1 ON, PGA=1, NORMAL MODE
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);		//…
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);
	SPI.transfer(ADS_SS, ADS_GAIN01 | ModeADS, SPI_CONTINUE);

	//test GPIO --This function stop the SPI. Remember to erase SPI_CONTINUE from the previous line if you comment this line
	//GPIOinitialize(GPIO1_OUTPUT_ON + GPIO2_OUTPUT_ON + GPIO3_OUTPUT_ON + GPIO4_OUTPUT_ON);

	SPI.transfer(ADS_SS, GPIO | _WREG, SPI_CONTINUE);	//Write Reg GPIO… GPIO + 0x40
	SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);
	SPI.transfer(ADS_SS, GPIO1_OUTPUT_ON | GPIO2_OUTPUT_ON | GPIO3_OUTPUT_ON | GPIO4_OUTPUT_ON, SPI_CONTINUE);		//GPIOA-B-C-D as input/output and set HIGH/LOW

	SPI.transfer(ADS_SS, GPIO | _WREG, SPI_CONTINUE);	//Write Reg GPIO… GPIO + 0x40
	SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);
	SPI.transfer(ADS_SS, GPIO1_OUTPUT_ON | GPIO2_OUTPUT_ON | GPIO3_OUTPUT_ON | GPIO4_OUTPUT_ON, SPI_CONTINUE);		//GPIOA-B-C-D as input/output and set HIGH/LOW

	SPI.transfer(ADS_SS, GPIO | _WREG, SPI_CONTINUE);	//Write Reg GPIO… GPIO + 0x40
	SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);
	SPI.transfer(ADS_SS, GPIO1_OUTPUT_ON | GPIO2_OUTPUT_ON | GPIO3_OUTPUT_ON | GPIO4_OUTPUT_ON);		//GPIOA-B-C-D as input/output and set HIGH/LOW

}

//reset all the ADS1298's settings.  Call however you'd like.  Stops all data acquisition
void ADS1298::resetADS()
{

	SPI.transfer(ADS_SS, _RESET, SPI_CONTINUE);		//send RESET command to default all registers
	delayMicroseconds(12);    	//must wait 18 tCLK cycles to execute this command

	SPI.transfer(ADS_SS, _SDATAC);		//stop read data so registers can be written… 0x11
	delayMicroseconds(3);   	//must wait 4 tCLK cycles after executing this command

	delay(100);

};

// Start continuous data acquisition
void ADS1298::startADS(void)
{

	RDATAC();
	delay(1);   // enter Read Data Continuous mode
	START();        // start the data acquisition
	delay(1);
	isRunning = true;

}

//write as binary each channel's 2 bytes of data
void ADS1298::writeADSchannelData(byte TriggerWord)
{
	//print rawChannelData array
	byte Trigger = 0xF0 | TriggerWord;
	byte ADCbyte = 0xF0;
	SerialUSB.write(ADCbyte);
	SerialUSB.write(Trigger);
	SerialUSB.write(bit24ChannelData, _NUMBEROFADS * _NUMBEROFBYTES);
}

// Stop the continuous data acquisition
void ADS1298::stopADS(void)
{
	STOP();
	delay(1);       // start the data acquisition
	SDATAC();
	delay(1);       // exit Read Data Continuous mode to communicate with ADS
	isRunning = false;
}

//start data conversion
void ADS1298::START()
{
	SPI.transfer(ADS_SS, _START);
}

//stop data conversion
void ADS1298::STOP()
{
	SPI.transfer(ADS_SS, _STOP);
}

//read data continuous mode
void ADS1298::RDATAC()
{
	SPI.transfer(ADS_SS, _RDATAC);
	delayMicroseconds(3);
}

//Single Read data
void ADS1298::RDATA()
{

	byte inByte;            			//  to read in one sample of the channels
	int byteCounter = 0;
	byte bits = 0;
	SPI.transfer(ADS_SS, _RDATA, SPI_CONTINUE);  				//  send the RDATA command

	for (int j = 0; j < _NUMBEROFADS; j++)
	{
		for (int i = 0; i < 3; i++){
			stat[i] = SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);     	//  read status register (1100 + LOFF_STATP + LOFF_STATN + GPIO[7:4])
			if (j>1 && i == 0 && _NUMBEROFADS > 2) {
				for (int k = 0; k < j; k++)
					bits = bits | bitRead(bit24ChannelData[byteCounter], 7 - k) << (k);
				bit24ChannelData[byteCounter - 1] = (bit24ChannelData[byteCounter - 1] << j - 1) | bits;
			}
		}
		for (int i = 0; i < _NUMBEROFBYTES; i++)
		{
			// read new channel data
			if (i == _NUMBEROFBYTES - 1 && _NUMBEROFADS == 1)
				inByte = SPI.transfer(ADS_SS, 0x00);
			else
				inByte = SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);

			bit24ChannelData[byteCounter] = inByte;  //raw data

			bits = 0;
			if (i>0)
				for (int k = 0; k < j; k++)
					bits = bits | bitRead(bit24ChannelData[byteCounter], 7 - k) << (k);
			if (i>0 && j>0)
				bit24ChannelData[byteCounter - 1] = (bit24ChannelData[byteCounter - 1] << j) | bits;
			byteCounter++;

		}
	}

	if (_NUMBEROFADS > 1){
		inByte = SPI.transfer(ADS_SS, 0x00);
		bit24ChannelData[byteCounter] = inByte;
		bits = 0;
		for (int k = 0; k < _NUMBEROFADS - 1; k++)
			bits = bits | bitRead(bit24ChannelData[byteCounter], 7 - k) << (k);

		bit24ChannelData[byteCounter - 1] = (bit24ChannelData[byteCounter - 1] << _NUMBEROFADS - 1) | bits;
	}
}

//stop read data continuous mode
void ADS1298::SDATAC()
{
	SPI.transfer(ADS_SS, _SDATAC);
	delayMicroseconds(3);   //must wait 4 tCLK cycles after executing this command
}

// Used to get the DeviceID
byte ADS1298::getDeviceID()
{
	// simple hello world com check
	SPI.transfer(ADS_SS, ID | _RREG, SPI_CONTINUE);	//Read ID Reg
	SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);

	byte data = SPI.transfer(ADS_SS, 0x00);	//Read value of ID Register

	//print value in HEX
	SerialUSB.print(F("Device ID: "));
	printHex(data);
	SerialUSB.print(F(" —> "));
	printBin(data);
	SerialUSB.println();

	return data;
}

// ADS GPIO select as input or output and if output pins set value
void ADS1298::GPIOinitialize(byte _set)
{
	SPI.begin(ADS_SS);
	SPI.setClockDivider(ADS_SS, 42);
	SPI.setDataMode(ADS_SS, SPI_MODE1);
	SPI.setBitOrder(ADS_SS, MSBFIRST);

	SPI.transfer(ADS_SS, GPIO | _WREG, SPI_CONTINUE);	//Write Reg GPIO… GPIO + 0x40
	SPI.transfer(ADS_SS, 0x00, SPI_CONTINUE);
	SPI.transfer(ADS_SS, _set);		//GPIOA-B-C-D as input/output and set HIGH/LOW
}

// Used for printing HEX data
void ADS1298::printHex(byte _data)
{
	SerialUSB.print(F("0x"));
	if (_data < 0x10)
		SerialUSB.print(F("0"));
	SerialUSB.print(_data, HEX);
}

// Used for printing BIN data
void ADS1298::printBin(byte _data)
{
	SerialUSB.print(F("B"));
	SerialUSB.print(_data, BIN);
}

// Used for printing Channel values in HEX format
void ADS1298::printCHvalueHex(word _data)
{
	SerialUSB.print(F("0x"));
	if (_data < 0x0010)
	{
		SerialUSB.print(F("000"));
		SerialUSB.print(_data, HEX);
	}
	else if (_data < 0x0100)
	{
		SerialUSB.print(F("00"));
		SerialUSB.print(_data, HEX);
	}
	else if (_data < 0x1000)
	{
		SerialUSB.print(F("0"));
		SerialUSB.print(_data, HEX);
	}
	else
		SerialUSB.print(_data, HEX);
 }

// ADS Slave Select
void ADS1298::csLow()
{
	digitalWrite(ADS_SS, LOW);
	delayMicroseconds(5);

	//SPI.beginTransaction(settingsADS1198);
}

void ADS1298::csHigh()
{
	//SPI.endTransaction();
	digitalWrite(ADS_SS, HIGH);
	delayMicroseconds(5);
}
<commit_msg>Delete ADS1298.cpp<commit_after><|endoftext|>


<commit_before>#include <SFML-Book/Stats.hpp>
#include <SFML-Book/Configuration.hpp>

#define FONT_SIZE   24

namespace book
{

Stats::Stats()
{
   reset();
}

void Stats::reset()
{
    _nb_rows = 0;
    _nb_score = 0;
    _nb_lvl = 0;
    _is_game_over = false;
    _initial_lvl = 0;

    _text_rows.setFont(Configuration::fonts.get(Configuration::Fonts::Gui));
    _text_rows.setString("rows : 0");
    _text_rows.setCharacterSize(FONT_SIZE);
    _text_rows.setPosition(0,0);

    _text_score.setFont(Configuration::fonts.get(Configuration::Gui));
    _text_score.setString("score : 0");
    _text_score.setCharacterSize(FONT_SIZE);
    _text_score.setPosition(0,FONT_SIZE + 1);

    _text_lvl.setFont(Configuration::fonts.get(Configuration::Gui));
    _text_lvl.setCharacterSize(FONT_SIZE);
    _text_lvl.setPosition(0,(FONT_SIZE + 1)*2);
    setLevel(0);

    _text_game_over.setFont(Configuration::fonts.get(Configuration::Gui));
    _text_game_over.setString("Game Over");
    _text_game_over.setCharacterSize(72);
    _text_game_over.setPosition(0,0);
}

bool Stats::isGameOver()const
{
    return _is_game_over;
}

void Stats::setGameOver(bool g)
{
    _is_game_over = g;
}

void Stats::setLevel(int lvl)
{
    _initial_lvl = lvl;
    _text_lvl.setString("lvl : "+std::to_string(lvl));
}

int Stats::getLevel()const
{
    return _initial_lvl + _nb_lvl;
}

void Stats::addLines(int lines)
{
    if(lines > 0)
    {
        //update number of lines
        _nb_rows += lines;
        _text_rows.setString("rows : "+std::to_string(_nb_rows));

        //update the score
        _text_score.setString("score : "+std::to_string(_nb_score));

        switch (lines)
        {
            case 1 : _nb_score += 40 * (_nb_lvl+1);break;
            case 2 : _nb_score += 100 * (_nb_lvl+1);break;
            case 3 : _nb_score += 300 * (_nb_lvl+1);break;
            default : _nb_score += 1200 * (_nb_lvl+1);break;
        }

        _nb_lvl = _initial_lvl + (_nb_rows / 10);

        //update the lvl
        _text_lvl.setString("lvl : "+std::to_string(_nb_lvl));
    }
}

unsigned int Stats::getLvl()const
{
    return _nb_lvl;
}

void Stats::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    if(not _is_game_over)
    {
        //make states
        states.transform *= getTransform();

        //draw
        target.draw(_text_rows,states);
        target.draw(_text_score,states);
        target.draw(_text_lvl,states);
    }
    else
        target.draw(_text_game_over,states);
}

}
<commit_msg>fix point calculation<commit_after>#include <SFML-Book/Stats.hpp>
#include <SFML-Book/Configuration.hpp>

#define FONT_SIZE   24

namespace book
{

Stats::Stats()
{
   reset();
}

void Stats::reset()
{
    _nb_rows = 0;
    _nb_score = 0;
    _nb_lvl = 0;
    _is_game_over = false;
    _initial_lvl = 0;

    _text_rows.setFont(Configuration::fonts.get(Configuration::Fonts::Gui));
    _text_rows.setString("rows : 0");
    _text_rows.setCharacterSize(FONT_SIZE);
    _text_rows.setPosition(0,0);

    _text_score.setFont(Configuration::fonts.get(Configuration::Gui));
    _text_score.setString("score : 0");
    _text_score.setCharacterSize(FONT_SIZE);
    _text_score.setPosition(0,FONT_SIZE + 1);

    _text_lvl.setFont(Configuration::fonts.get(Configuration::Gui));
    _text_lvl.setCharacterSize(FONT_SIZE);
    _text_lvl.setPosition(0,(FONT_SIZE + 1)*2);
    setLevel(0);

    _text_game_over.setFont(Configuration::fonts.get(Configuration::Gui));
    _text_game_over.setString("Game Over");
    _text_game_over.setCharacterSize(72);
    _text_game_over.setPosition(0,0);
}

bool Stats::isGameOver()const
{
    return _is_game_over;
}

void Stats::setGameOver(bool g)
{
    _is_game_over = g;
}

void Stats::setLevel(int lvl)
{
    _initial_lvl = lvl;
    _text_lvl.setString("lvl : "+std::to_string(lvl));
}

int Stats::getLevel()const
{
    return _initial_lvl + _nb_lvl;
}

void Stats::addLines(int lines)
{
    if(lines > 0)
    {
        //update number of lines
        _nb_rows += lines;
        _text_rows.setString("rows : "+std::to_string(_nb_rows));

        //update the score
        _text_score.setString("score : "+std::to_string(_nb_score));

        switch (lines)
        {
            case 1 : _nb_score += 40 * ( _initial_lvl+_nb_lvl+1);break;
            case 2 : _nb_score += 100 * ( _initial_lvl+_nb_lvl+1);break;
            case 3 : _nb_score += 300 * ( _initial_lvl+_nb_lvl+1);break;
            default : _nb_score += 1200 * ( _initial_lvl+_nb_lvl+1);break;
        }

        _nb_lvl = _initial_lvl + (_nb_rows / 10);

        //update the lvl
        _text_lvl.setString("lvl : "+std::to_string(_nb_lvl));
    }
}

unsigned int Stats::getLvl()const
{
    return _nb_lvl;
}

void Stats::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    if(not _is_game_over)
    {
        //make states
        states.transform *= getTransform();

        //draw
        target.draw(_text_rows,states);
        target.draw(_text_score,states);
        target.draw(_text_lvl,states);
    }
    else
        target.draw(_text_game_over,states);
}

}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/Synth.hpp"
#include "Methcla/Audio/SynthDef.hpp"

#include <iostream>
#include <memory>
#include <utility>

using namespace boost;
using namespace Methcla::Audio;
using namespace std;

SynthDef::SynthDef(const Methcla_SynthDef* synthDef)
    : m_descriptor(synthDef)
    // , m_numAudioInputs(0)
    // , m_numAudioOutputs(0)
    // , m_numControlInputs(0)
    // , m_numControlOutputs(0)
{
    // Methcla_Port port;
    // std::memset(&port, 0, sizeof(port));
    // for (size_t i=0; m_descriptor->port(m_descriptor, nullptr, i, &port); i++) {
    //     switch (port.type) {
    //         case kMethcla_AudioPort:
    //             switch (port.direction) {
    //                 case kMethcla_Input:
    //                     m_ports.push_back(Port(port, m_numAudioInputs));
    //                     m_numAudioInputs++;
    //                     break;
    //                 case kMethcla_Output:
    //                     m_ports.push_back(Port(port, m_numAudioOutputs));
    //                     m_numAudioOutputs++;
    //                     break;
    //             }
    //             break;
    //         case kMethcla_ControlPort:
    //             switch (port.direction) {
    //                 case kMethcla_Input:
    //                     m_ports.push_back(Port(port, m_numControlInputs));
    //                     m_numControlInputs++;
    //                     break;
    //                 case kMethcla_Output:
    //                     m_ports.push_back(Port(port, m_numControlOutputs));
    //                     m_numControlOutputs++;
    //                     break;
    //             }
    //     }
    // }

    // Validate descriptor fields (some are optional)
    if (m_descriptor->uri == nullptr || m_descriptor->uri[0] == '\0')
        throw std::invalid_argument("SynthDef: Missing URI");
    if (m_descriptor->construct == nullptr)
        throw std::invalid_argument("SynthDef: Missing `construct' function");
    if (m_descriptor->port_descriptor == nullptr)
        throw std::invalid_argument("SynthDef: Missing `port_descriptor' function");
    if (m_descriptor->connect == nullptr)
        throw std::invalid_argument("SynthDef: Missing `connect' function");
    if (m_descriptor->process == nullptr)
        throw std::invalid_argument("SynthDef: Missing `process' function");

    m_options = m_descriptor->options_size > 0 ? new char[m_descriptor->options_size] : nullptr;

    std::cerr << "SynthDef " << uri() << " loaded (" << m_descriptor << "):" << std::endl
              << "    instance size: " << instanceSize() << std::endl;
              // << "    control inputs: " << numControlInputs() << std::endl
              // << "    control outputs: " << numControlOutputs() << std::endl
              // << "    audio inputs: " << numAudioInputs() << std::endl
              // << "    audio outputs: " << numAudioOutputs() << std::endl;
}

SynthDef::~SynthDef()
{
    delete [] static_cast<char*>(m_options);
}

const Methcla_SynthOptions* SynthDef::configure(OSCPP::Server::ArgStream options) const
{
    if (m_descriptor->configure) {
        auto state = options.state();
        m_descriptor->configure(
            std::get<0>(state).pos(), std::get<0>(state).consumable(),
            std::get<1>(state).pos(), std::get<1>(state).consumable(),
            m_options
        );
        return m_options;
    }
    return nullptr;
}

bool SynthDef::portDescriptor(const Methcla_SynthOptions* options, size_t index, Methcla_PortDescriptor* port) const
{
    return m_descriptor->port_descriptor(options, index, port);
}

void SynthDef::construct(const Methcla_World* world, const Methcla_SynthOptions* options, Synth* owner, Methcla_Synth* synth) const
{
    m_descriptor->construct(world, m_descriptor, options, static_cast<Reference*>(owner), synth);
}

void SynthDef::destroy(const Methcla_World* world, Methcla_Synth* synth) const
{
    if (m_descriptor->destroy) m_descriptor->destroy(world, synth);
}

PluginLibrary::PluginLibrary(const Methcla_Library* lib, std::shared_ptr<Methcla::Plugin::Library> plugin)
    : m_lib(lib)
    , m_plugin(plugin)
{
}

PluginLibrary::~PluginLibrary()
{
    methcla_library_destroy(m_lib);
}

void PluginManager::loadPlugins(const Methcla_Host* host, const std::list<Methcla_LibraryFunction>& funcs)
{
    for (auto f : funcs) {
        const Methcla_Library* lib = f(host, ".");
        if (lib != nullptr) {
            m_libs.push_back(std::make_shared<PluginLibrary>(lib));
        }
    }
}

void PluginManager::loadPlugins(const Methcla_Host* host, const std::string& directory)
{
    std::cout << "PluginManager::loadPlugins not yet implemented" << std::endl;
}
<commit_msg>Remove stale code<commit_after>// Copyright 2012-2013 Samplecount S.L.
//
// 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 "Methcla/Audio/Synth.hpp"
#include "Methcla/Audio/SynthDef.hpp"

#include <iostream>
#include <memory>
#include <utility>

using namespace boost;
using namespace Methcla::Audio;
using namespace std;

SynthDef::SynthDef(const Methcla_SynthDef* synthDef)
    : m_descriptor(synthDef)
{
    // Validate descriptor fields (some are optional)
    if (m_descriptor->uri == nullptr || m_descriptor->uri[0] == '\0')
        throw std::invalid_argument("SynthDef: Missing URI");
    if (m_descriptor->construct == nullptr)
        throw std::invalid_argument("SynthDef: Missing `construct' function");
    if (m_descriptor->port_descriptor == nullptr)
        throw std::invalid_argument("SynthDef: Missing `port_descriptor' function");
    if (m_descriptor->connect == nullptr)
        throw std::invalid_argument("SynthDef: Missing `connect' function");
    if (m_descriptor->process == nullptr)
        throw std::invalid_argument("SynthDef: Missing `process' function");

    m_options = m_descriptor->options_size > 0 ? new char[m_descriptor->options_size] : nullptr;

#if DEBUG
    std::cerr << "SynthDef " << uri() << " loaded (" << m_descriptor << "):" << std::endl
              << "    instance size: " << instanceSize() << std::endl;
#endif
}

SynthDef::~SynthDef()
{
    delete [] static_cast<char*>(m_options);
}

const Methcla_SynthOptions* SynthDef::configure(OSCPP::Server::ArgStream options) const
{
    if (m_descriptor->configure) {
        auto state = options.state();
        m_descriptor->configure(
            std::get<0>(state).pos(), std::get<0>(state).consumable(),
            std::get<1>(state).pos(), std::get<1>(state).consumable(),
            m_options
        );
        return m_options;
    }
    return nullptr;
}

bool SynthDef::portDescriptor(const Methcla_SynthOptions* options, size_t index, Methcla_PortDescriptor* port) const
{
    return m_descriptor->port_descriptor(options, index, port);
}

void SynthDef::construct(const Methcla_World* world, const Methcla_SynthOptions* options, Synth* owner, Methcla_Synth* synth) const
{
    m_descriptor->construct(world, m_descriptor, options, static_cast<Reference*>(owner), synth);
}

void SynthDef::destroy(const Methcla_World* world, Methcla_Synth* synth) const
{
    if (m_descriptor->destroy) m_descriptor->destroy(world, synth);
}

PluginLibrary::PluginLibrary(const Methcla_Library* lib, std::shared_ptr<Methcla::Plugin::Library> plugin)
    : m_lib(lib)
    , m_plugin(plugin)
{
}

PluginLibrary::~PluginLibrary()
{
    methcla_library_destroy(m_lib);
}

void PluginManager::loadPlugins(const Methcla_Host* host, const std::list<Methcla_LibraryFunction>& funcs)
{
    for (auto f : funcs) {
        const Methcla_Library* lib = f(host, ".");
        if (lib != nullptr) {
            m_libs.push_back(std::make_shared<PluginLibrary>(lib));
        }
    }
}

void PluginManager::loadPlugins(const Methcla_Host* host, const std::string& directory)
{
    std::cout << "PluginManager::loadPlugins not yet implemented" << std::endl;
}
<|endoftext|>