<commit_before>#include "gtest/gtest.h"

#include <fstream>

#include <ydsh/ydsh.h>
#include <constant.h>
#include <vm.h>

#include "../test_common.h"

class HistoryTest : public ExpectOutput, public TempFileFactory {
protected:
    DSState *state{nullptr};

public:
    HistoryTest() {
        this->state = DSState_create();
        std::string value;
        value += '"';
        value += this->tmpFileName;
        value += '"';
        this->assignValue(VAR_HISTFILE, std::move(value));
    }

    ~HistoryTest() override {
        DSState_delete(&this->state);
    }

    void setHistSize(unsigned int size, bool sync = true) {
        this->assignUintValue(VAR_HISTSIZE, size);
        if(sync) {
            DSState_syncHistorySize(this->state);
        }
    }

    void setHistFileSize(unsigned int size) {
        this->assignUintValue(VAR_HISTFILESIZE, size);
    }

    template <typename ...T>
    void history(T && ...arg) {
        constexpr auto size = sizeof...(T) + 2;
        std::array<const char *, size> argv = { "history", std::forward<T>(arg)..., nullptr };
        this->exec(argv.data());
    }

    void addHistory(const char *value) {
        this->history("-s", value);
    }

    void clearHistory() {
        this->history("-c");
    }

    void loadHistory(const char *fileName = nullptr) {
        this->history("-r", fileName);
    }

    void saveHistory(const char *fileName = nullptr) {
        this->history("-w", fileName);
    }

private:
    void assignValue(const char *varName, std::string &&value) {
        std::string str = "$";
        str += varName;
        str += " = ";
        str += value;

        auto r = DSState_eval(this->state, "(dummy)", str.c_str(), str.size(), nullptr);
        SCOPED_TRACE("");
        ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(r == 0));
    }

    void assignUintValue(const char *varName, unsigned int value) {
        std::string str = std::to_string(value);
        str += "u";
        this->assignValue(varName, std::move(str));
    }

    void exec(const char **argv) {
        int s = DSState_getExitStatus(this->state);
        DSState_exec(this->state, (char **)argv);
        DSState_setExitStatus(this->state, s);
    }
};

TEST_F(HistoryTest, base) {
    SCOPED_TRACE("");
    auto *history = DSState_history(this->state);

    // default size
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(0u, DSHistory_size(history)));

    // after synchronization (call DSState_syncHistory)
    this->setHistSize(100, false);
    DSState_syncHistorySize(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(0u, DSHistory_size(history)));
}

TEST_F(HistoryTest, add) {
    this->setHistSize(2);
    this->addHistory("aaa");
    this->addHistory("bbb");

    auto *history = DSState_history(this->state);

    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));

    this->addHistory("ccc");
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ccc", DSHistory_get(history, 1)));

    this->addHistory("ccc");
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
}

TEST_F(HistoryTest, set) {
    SCOPED_TRACE("");

    this->setHistSize(10);
    this->addHistory("aaa");
    this->addHistory("bbb");

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));

    DSHistory_set(history, 1, "ccc");
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ccc", DSHistory_get(history, 1)));

    DSHistory_set(history, 3, "ccc");    // do nothing, if out of range
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));

    DSHistory_set(history, 1000, "ccc");    // do nothing, if out of range
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
}

TEST_F(HistoryTest, remove) {
    SCOPED_TRACE("");

    this->setHistSize(10);
    this->addHistory("aaa");
    this->addHistory("bbb");
    this->addHistory("ccc");
    this->addHistory("ddd");
    this->addHistory("eee");

    auto *history = DSState_history(this->state);
    DSHistory_delete(history, 2);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(4u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("eee", DSHistory_get(history, 3)));

    DSHistory_delete(history, 3);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(3u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));

    // do nothing, if out of range
    DSHistory_delete(history, 6);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(3u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));

    // do nothing, if out of range
    DSHistory_delete(history, 600);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(3u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));
}

TEST_F(HistoryTest, clear) {
    SCOPED_TRACE("");

    this->setHistSize(10);
    this->addHistory("aaa");
    this->addHistory("bbb");
    this->addHistory("ccc");
    this->addHistory("ddd");
    this->addHistory("eee");

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(5u, DSHistory_size(history)));

    this->clearHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(0u, DSHistory_size(history)));
}

TEST_F(HistoryTest, resize) {
    this->setHistSize(10);
    for(unsigned int i = 0; i < 10; i++) {
        this->addHistory(std::to_string(i).c_str());
    }

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));

    this->setHistSize(5);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(5u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("0", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("1", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("2", DSHistory_get(history, 2)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("3", DSHistory_get(history, 3)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("4", DSHistory_get(history, 4)));
}

TEST_F(HistoryTest, file) {
    this->setHistSize(10);
    for(unsigned int i = 0; i < 10; i++) {
        this->addHistory(std::to_string(i).c_str());
    }

    auto *history = DSState_history(this->state);
    this->setHistFileSize(15);
    /**
     * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
     */
    this->saveHistory();
    this->clearHistory();
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));

    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i).c_str(), DSHistory_get(history, i)));
    }

    for(unsigned int i = 0; i < 5; i++) {
        this->addHistory(std::to_string(i + 10).c_str());
    }

    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 5).c_str(), DSHistory_get(history, i)));
    }

    /**
     * previous hist file content
     * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
     *
     * newly added content
     * 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
     *
     * current hist file content
     * 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
     */
    this->saveHistory();
    this->clearHistory();
    this->setHistSize(15);
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));
    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 5).c_str(), DSHistory_get(history, i)));
    }

    // not overwrite history file when buffer size is 0
    this->clearHistory();
    this->saveHistory();
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));
    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 5).c_str(), DSHistory_get(history, i)));
    }

    // not overwrite history file when hist file size is 0
    this->setHistFileSize(0);
    this->clearHistory();
    this->addHistory("hoge");
    this->saveHistory();
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(11u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("hoge", DSHistory_get(history, 0)));
    for(unsigned int i = 1; i < 11; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 4).c_str(), DSHistory_get(history, i)));
    }
}

TEST_F(HistoryTest, file2) {
    this->setHistFileSize(DS_HISTFILESIZE_LIMIT + 10);
    this->setHistSize(DS_HISTFILESIZE_LIMIT);

    for(unsigned int i = 0; i < DS_HISTFILESIZE_LIMIT; i++) {
        this->addHistory(std::to_string(i).c_str());
    }

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(DS_HISTFILESIZE_LIMIT, DSHistory_size(history)));

    this->saveHistory();
    this->clearHistory();
    this->loadHistory();

    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(DS_HISTFILESIZE_LIMIT, DSHistory_size(history)));
    for(unsigned int i = 0; i < DS_HISTFILESIZE_LIMIT; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i).c_str(), DSHistory_get(history, i)));
    }
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}<commit_msg>fix build error<commit_after>#include "gtest/gtest.h"

#include <fstream>

#include <ydsh/ydsh.h>
#include <constant.h>
#include <vm.h>

#include "../test_common.h"

class HistoryTest : public ExpectOutput, public TempFileFactory {
protected:
    DSState *state{nullptr};

public:
    HistoryTest() {
        this->state = DSState_create();
        std::string value;
        value += '"';
        value += this->tmpFileName;
        value += '"';
        this->assignValue(VAR_HISTFILE, std::move(value));
    }

    ~HistoryTest() override {
        DSState_delete(&this->state);
    }

    void setHistSize(unsigned int size, bool sync = true) {
        this->assignUintValue(VAR_HISTSIZE, size);
        if(sync) {
            DSState_syncHistorySize(this->state);
        }
    }

    void setHistFileSize(unsigned int size) {
        this->assignUintValue(VAR_HISTFILESIZE, size);
    }

    template <typename ...T>
    void history(T && ...arg) {
        constexpr auto size = sizeof...(T) + 2;
        std::array<const char *, size> argv = {{ "history", std::forward<T>(arg)..., nullptr }};
        this->exec(argv.data());
    }

    void addHistory(const char *value) {
        this->history("-s", value);
    }

    void clearHistory() {
        this->history("-c");
    }

    void loadHistory(const char *fileName = nullptr) {
        this->history("-r", fileName);
    }

    void saveHistory(const char *fileName = nullptr) {
        this->history("-w", fileName);
    }

private:
    void assignValue(const char *varName, std::string &&value) {
        std::string str = "$";
        str += varName;
        str += " = ";
        str += value;

        auto r = DSState_eval(this->state, "(dummy)", str.c_str(), str.size(), nullptr);
        SCOPED_TRACE("");
        ASSERT_NO_FATAL_FAILURE(ASSERT_TRUE(r == 0));
    }

    void assignUintValue(const char *varName, unsigned int value) {
        std::string str = std::to_string(value);
        str += "u";
        this->assignValue(varName, std::move(str));
    }

    void exec(const char **argv) {
        int s = DSState_getExitStatus(this->state);
        DSState_exec(this->state, (char **)argv);
        DSState_setExitStatus(this->state, s);
    }
};

TEST_F(HistoryTest, base) {
    SCOPED_TRACE("");
    auto *history = DSState_history(this->state);

    // default size
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(0u, DSHistory_size(history)));

    // after synchronization (call DSState_syncHistory)
    this->setHistSize(100, false);
    DSState_syncHistorySize(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(0u, DSHistory_size(history)));
}

TEST_F(HistoryTest, add) {
    this->setHistSize(2);
    this->addHistory("aaa");
    this->addHistory("bbb");

    auto *history = DSState_history(this->state);

    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));

    this->addHistory("ccc");
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ccc", DSHistory_get(history, 1)));

    this->addHistory("ccc");
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
}

TEST_F(HistoryTest, set) {
    SCOPED_TRACE("");

    this->setHistSize(10);
    this->addHistory("aaa");
    this->addHistory("bbb");

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));

    DSHistory_set(history, 1, "ccc");
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ccc", DSHistory_get(history, 1)));

    DSHistory_set(history, 3, "ccc");    // do nothing, if out of range
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));

    DSHistory_set(history, 1000, "ccc");    // do nothing, if out of range
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(2u, DSHistory_size(history)));
}

TEST_F(HistoryTest, remove) {
    SCOPED_TRACE("");

    this->setHistSize(10);
    this->addHistory("aaa");
    this->addHistory("bbb");
    this->addHistory("ccc");
    this->addHistory("ddd");
    this->addHistory("eee");

    auto *history = DSState_history(this->state);
    DSHistory_delete(history, 2);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(4u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("eee", DSHistory_get(history, 3)));

    DSHistory_delete(history, 3);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(3u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));

    // do nothing, if out of range
    DSHistory_delete(history, 6);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(3u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));

    // do nothing, if out of range
    DSHistory_delete(history, 600);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(3u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("aaa", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("bbb", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("ddd", DSHistory_get(history, 2)));
}

TEST_F(HistoryTest, clear) {
    SCOPED_TRACE("");

    this->setHistSize(10);
    this->addHistory("aaa");
    this->addHistory("bbb");
    this->addHistory("ccc");
    this->addHistory("ddd");
    this->addHistory("eee");

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(5u, DSHistory_size(history)));

    this->clearHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(0u, DSHistory_size(history)));
}

TEST_F(HistoryTest, resize) {
    this->setHistSize(10);
    for(unsigned int i = 0; i < 10; i++) {
        this->addHistory(std::to_string(i).c_str());
    }

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));

    this->setHistSize(5);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(5u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("0", DSHistory_get(history, 0)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("1", DSHistory_get(history, 1)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("2", DSHistory_get(history, 2)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("3", DSHistory_get(history, 3)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("4", DSHistory_get(history, 4)));
}

TEST_F(HistoryTest, file) {
    this->setHistSize(10);
    for(unsigned int i = 0; i < 10; i++) {
        this->addHistory(std::to_string(i).c_str());
    }

    auto *history = DSState_history(this->state);
    this->setHistFileSize(15);
    /**
     * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
     */
    this->saveHistory();
    this->clearHistory();
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));

    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i).c_str(), DSHistory_get(history, i)));
    }

    for(unsigned int i = 0; i < 5; i++) {
        this->addHistory(std::to_string(i + 10).c_str());
    }

    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 5).c_str(), DSHistory_get(history, i)));
    }

    /**
     * previous hist file content
     * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
     *
     * newly added content
     * 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
     *
     * current hist file content
     * 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
     */
    this->saveHistory();
    this->clearHistory();
    this->setHistSize(15);
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));
    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 5).c_str(), DSHistory_get(history, i)));
    }

    // not overwrite history file when buffer size is 0
    this->clearHistory();
    this->saveHistory();
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(10u, DSHistory_size(history)));
    for(unsigned int i = 0; i < 10; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 5).c_str(), DSHistory_get(history, i)));
    }

    // not overwrite history file when hist file size is 0
    this->setHistFileSize(0);
    this->clearHistory();
    this->addHistory("hoge");
    this->saveHistory();
    this->loadHistory();
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(11u, DSHistory_size(history)));
    ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ("hoge", DSHistory_get(history, 0)));
    for(unsigned int i = 1; i < 11; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i + 4).c_str(), DSHistory_get(history, i)));
    }
}

TEST_F(HistoryTest, file2) {
    this->setHistFileSize(DS_HISTFILESIZE_LIMIT + 10);
    this->setHistSize(DS_HISTFILESIZE_LIMIT);

    for(unsigned int i = 0; i < DS_HISTFILESIZE_LIMIT; i++) {
        this->addHistory(std::to_string(i).c_str());
    }

    auto *history = DSState_history(this->state);
    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(DS_HISTFILESIZE_LIMIT, DSHistory_size(history)));

    this->saveHistory();
    this->clearHistory();
    this->loadHistory();

    ASSERT_NO_FATAL_FAILURE(ASSERT_EQ(DS_HISTFILESIZE_LIMIT, DSHistory_size(history)));
    for(unsigned int i = 0; i < DS_HISTFILESIZE_LIMIT; i++) {
        ASSERT_NO_FATAL_FAILURE(ASSERT_STREQ(std::to_string(i).c_str(), DSHistory_get(history, i)));
    }
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}<|endoftext|>


<commit_before>#include "catch.hpp"
#include "EventThreader.hpp"

TEST_CASE( "EventThreader", "[EventThreader]" ) {
	std::stringstream ss;

	SECTION("Abitrary use") {
		/* Example of most basic use */
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			for(int i = 0; i < 100; i++) { ss << "*"; }
			switchToMainThread();
			for(int i = 0; i < 50; i++) { ss << "*"; }
			switchToMainThread();
		};
		EventThreader et(f);
		et.switchToEventThread();
		for(int i = 0; i < 75; i++) { ss << "$"; }
		et.switchToEventThread();
		for(int i = 0; i < 25; i++) { ss << "$"; }
		et.join();

		/* Generate what the result should look like */
		std::string requirement;
		for(int i = 0; i < 100; i++) { requirement += "*"; }
		for(int i = 0; i < 75; i++) { requirement += "$"; }
		for(int i = 0; i < 50; i++) { requirement += "*"; }
		for(int i = 0; i < 25; i++) { requirement += "$"; }
		REQUIRE( requirement == ss.str());

	}

	SECTION("Empty event - no switch, most basic use") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){};
		EventThreader et(f);
		et.join();
		REQUIRE( ss.str() == "" );
	}

	SECTION("Empty event - no switch, main prints a thing") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){};
		EventThreader et(f);
		ss << "here";
		et.join();
		REQUIRE( ss.str() == "here" );
	}

	SECTION("event is run without switch") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		et.join();
		REQUIRE( ss.str() == "f" );
	}

	SECTION("event is run at join (not asked to run before)") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		ss << "p";
		et.join();
		REQUIRE( ss.str() == "pf" );
	}

	SECTION("one switch to event without a switch to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_AS(et.switchToEventThread(), std::runtime_error);
	}

	SECTION("one switch to event without a switch to main - text") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_WITH(et.switchToEventThread(), "switch to event not matched with a switch to calling");
	}

	SECTION("two switches to event with no switches to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_AS(et.switchToEventThread(), std::runtime_error);
		REQUIRE_THROWS_AS(et.switchToEventThread(), std::runtime_error);
	}

	SECTION("two switches to event with no switches to main - text") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_WITH(et.switchToEventThread(), "switch to event not matched with a switch to calling");
		REQUIRE_THROWS_WITH(et.switchToEventThread(), "switch to event not matched with a switch to calling");
	}

	SECTION("print order") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << 1;
			switchToMainThread();
			ss << 3;
			switchToMainThread();
			ss << 5;
			switchToMainThread();
		};
		EventThreader et(f);
		ss << 0;
		et.switchToEventThread();
		ss << 2;
		et.switchToEventThread();
		ss << 4;
		et.switchToEventThread();
		ss << 6;
		et.join();
		REQUIRE( ss.str() == "0123456" );
	}

	SECTION("no event switch to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "1";
			ss << "2";
		};
		EventThreader et(f);
		et.join();
		REQUIRE( ss.str() == "12" );
	}

	SECTION("one event switch to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "1";
			switchToMainThread();
			ss << "2";
		};
		EventThreader et(f);
		et.switchToEventThread();
		et.join();
		REQUIRE( ss.str() == "12" );
	}

	SECTION("premiture join with exception message") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			switchToMainThread();
			switchToMainThread();
		};
		EventThreader et(f);
		et.switchToEventThread();
		REQUIRE_THROWS_WITH(et.join(), "switch to calling not matched with a switch to event");
	}

	SECTION("clean up") {
		int var = 100;
		auto f = [&var](std::function<void(void)> switchToMainThread){
			var = 1;
			switchToMainThread();
		};
		EventThreader et(f);
		et.setEventCleanup([&var](){
			var = 10;
		});
		REQUIRE( var == 100);
		et.switchToEventThread();
		REQUIRE( var == 1);
		et.join();
		REQUIRE( var = 10 );

	}
}
<commit_msg>bring coverage up to >80%<commit_after>#include "catch.hpp"
#include "EventThreader.hpp"

TEST_CASE( "EventThreader", "[EventThreader]" ) {
	std::stringstream ss;

	SECTION("Abitrary use") {
		/* Example of most basic use */
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			for(int i = 0; i < 100; i++) { ss << "*"; }
			switchToMainThread();
			for(int i = 0; i < 50; i++) { ss << "*"; }
			switchToMainThread();
		};
		EventThreader et(f);
		et.switchToEventThread();
		for(int i = 0; i < 75; i++) { ss << "$"; }
		et.switchToEventThread();
		for(int i = 0; i < 25; i++) { ss << "$"; }
		et.join();

		/* Generate what the result should look like */
		std::string requirement;
		for(int i = 0; i < 100; i++) { requirement += "*"; }
		for(int i = 0; i < 75; i++) { requirement += "$"; }
		for(int i = 0; i < 50; i++) { requirement += "*"; }
		for(int i = 0; i < 25; i++) { requirement += "$"; }
		REQUIRE( requirement == ss.str());

	}

	SECTION("Empty event - no switch, most basic use") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){};
		EventThreader et(f);
		et.join();
		REQUIRE( ss.str() == "" );
	}

	SECTION("Empty event - no switch, main prints a thing") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){};
		EventThreader et(f);
		ss << "here";
		et.join();
		REQUIRE( ss.str() == "here" );
	}

	SECTION("event is run without switch") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		et.join();
		REQUIRE( ss.str() == "f" );
	}

	SECTION("event is run at join (not asked to run before)") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		ss << "p";
		et.join();
		REQUIRE( ss.str() == "pf" );
	}

	SECTION("one switch to event without a switch to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_AS(et.switchToEventThread(), std::runtime_error);
	}

	SECTION("one switch to event without a switch to main - text") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_WITH(et.switchToEventThread(), "switch to event not matched with a switch to calling");
	}

	SECTION("two switches to event with no switches to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_AS(et.switchToEventThread(), std::runtime_error);
		REQUIRE_THROWS_AS(et.switchToEventThread(), std::runtime_error);
	}

	SECTION("two switches to event with no switches to main - text") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "f";
		};
		EventThreader et(f);
		REQUIRE_THROWS_WITH(et.switchToEventThread(), "switch to event not matched with a switch to calling");
		REQUIRE_THROWS_WITH(et.switchToEventThread(), "switch to event not matched with a switch to calling");
	}

	SECTION("print order") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << 1;
			switchToMainThread();
			ss << 3;
			switchToMainThread();
			ss << 5;
			switchToMainThread();
		};
		EventThreader et(f);
		ss << 0;
		et.switchToEventThread();
		ss << 2;
		et.switchToEventThread();
		ss << 4;
		et.switchToEventThread();
		ss << 6;
		et.join();
		REQUIRE( ss.str() == "0123456" );
	}

	SECTION("no event switch to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "1";
			ss << "2";
		};
		EventThreader et(f);
		et.join();
		REQUIRE( ss.str() == "12" );
	}

	SECTION("one event switch to main") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			ss << "1";
			switchToMainThread();
			ss << "2";
		};
		EventThreader et(f);
		et.switchToEventThread();
		et.join();
		REQUIRE( ss.str() == "12" );
	}

	SECTION("premiture join with exception message") {
		auto f = [&ss](std::function<void(void)> switchToMainThread){
			switchToMainThread();
			switchToMainThread();
		};
		EventThreader et(f);
		et.switchToEventThread();
		REQUIRE_THROWS_WITH(et.join(), "switch to calling not matched with a switch to event");
	}

	SECTION("clean up") {
		int var = 100;
		auto f = [&var](std::function<void(void)> switchToMainThread){
			var = 1;
			switchToMainThread();
		};
		EventThreader et(f);
		et.setEventCleanup([&var](){
			var = 10;
		});
		REQUIRE( var == 100);
		et.switchToEventThread();
		REQUIRE( var == 1);
		et.join();
		REQUIRE( var == 10 );
	}
}
<|endoftext|>


<commit_before>#include <iostream>
#include "any.h"
#include "anyTest.h"

using ::testing::Return;

anyTest::anyTest() {
    // Have qux return true by default
    ON_CALL(m_bar,qux()).WillByDefault(Return(true));
    // Have norf return false by default
    ON_CALL(m_bar,norf()).WillByDefault(Return(false));
}

anyTest::~anyTest() {};

void anyTest::SetUp() {};

void anyTest::TearDown() {};

class testObject {
public:
    int _value;

    testObject(int val): _value{val}{}

};

std::ostream& operator<<(std::ostream& out, const testObject& b)
{
        out << b._value;

    return out ;
}

TEST_F(anyTest, typeBool) {
    any a0 = true;
    EXPECT_EQ( a0._<bool>() , true);

}

TEST_F(anyTest, typeChar) {
    any a1 = 'A';
    EXPECT_EQ( a1._<char>() , 'A');

}

TEST_F(anyTest, typeInt) {
    any a2 = 6;
    EXPECT_EQ( a2._<int>(), 6);

}

TEST_F(anyTest, typeDouble) {
    any a3 = 3.14;
    EXPECT_EQ( a3._<double>() , 3.14);

}

TEST_F(anyTest, typeChars) {
    any a4 = "hello,";
    auto expected = "hello,";
    EXPECT_EQ( a4._<const char*>() , expected);
}

TEST_F(anyTest, typeVectorInt) {
    any a5 = std::vector<int>{6, 5, 4, 3, 2, 1, 0};
    auto expected = std::vector<int>{ 6, 5, 4, 3, 2, 1, 0 };
    EXPECT_EQ( a5._<std::vector<int>>() , expected);
}

TEST_F(anyTest, typeString) {
    any a6 = std::string("world!");
    EXPECT_EQ( a6._<std::string>() , "world!");
}

TEST_F(anyTest, typeStruct) {
    any a7 = testObject{3};
    std::cout << "[7] testObject      : " << a7._<testObject>() << std::endl;
    EXPECT_TRUE(a7.is<testObject>());
}
<commit_msg>testing<commit_after>#include <iostream>
#include "any.h"
#include "anyTest.h"

using ::testing::Return;

anyTest::anyTest() {
    // Have qux return true by default
    ON_CALL(m_bar, qux()).WillByDefault(Return(true));
    // Have norf return false by default
    ON_CALL(m_bar, norf()).WillByDefault(Return(false));
}

anyTest::~anyTest() { };

void anyTest::SetUp() { };

void anyTest::TearDown() { };

class testObject {
public:
    int _value;

    testObject(int val) : _value{val} { }

};

std::ostream &operator<<(std::ostream &out, const testObject &b) {
    out << "testObject { int _value = " << b._value << "}";
    return out;
}

TEST_F(anyTest, typeBool) {
    any a0 = true;
    EXPECT_EQ(a0._<bool>(), true);

}

TEST_F(anyTest, typeChar) {
    any a1 = 'A';
    EXPECT_EQ(a1._<char>(), 'A');

}

TEST_F(anyTest, typeInt) {
    any a2 = 6;
    EXPECT_EQ(a2._<int>(), 6);

}

TEST_F(anyTest, typeDouble) {
    any a3 = 3.14;
    EXPECT_EQ(a3._<double>(), 3.14);

}

TEST_F(anyTest, typeChars) {
    any a4 = "hello,";
    auto expected = "hello,";
    EXPECT_EQ(a4._<const char *>(), expected);
}

TEST_F(anyTest, typeVectorInt) {
    any a5 = std::vector<int>{6, 5, 4, 3, 2, 1, 0};
    auto expected = std::vector<int>{6, 5, 4, 3, 2, 1, 0};
    EXPECT_EQ(a5._<std::vector<int>>(), expected);
}

TEST_F(anyTest, typeString) {
    any a6 = std::string("world!");
    EXPECT_EQ(a6._<std::string>(), "world!");
}

TEST_F(anyTest, typeStruct) {
    any a7 = testObject{3};
    std::cout << "[7] testObject      : " << a7._<testObject>() << std::endl;
    EXPECT_TRUE(a7.is<testObject>());
}
<|endoftext|>


<commit_before>#include "testsettings.hpp"
#ifdef TEST_COLUMN_DATETIME

#include <realm/column_datetime.hpp>
#include <realm.hpp>

#include "test.hpp"

using namespace realm;

// Test independence and thread-safety
// -----------------------------------
//
// All tests must be thread safe and independent of each other. This
// is required because it allows for both shuffling of the execution
// order and for parallelized testing.
//
// In particular, avoid using std::rand() since it is not guaranteed
// to be thread safe. Instead use the API offered in
// `test/util/random.hpp`.
//
// All files created in tests must use the TEST_PATH macro (or one of
// its friends) to obtain a suitable file system path. See
// `test/util/test_path.hpp`.
//
//
// Debugging and the ONLY() macro
// ------------------------------
//
// A simple way of disabling all tests except one called `Foo`, is to
// replace TEST(Foo) with ONLY(Foo) and then recompile and rerun the
// test suite. Note that you can also use filtering by setting the
// environment varible `UNITTEST_FILTER`. See `README.md` for more on
// this.
//
// Another way to debug a particular test, is to copy that test into
// `experiments/testcase.cpp` and then run `sh build.sh
// check-testcase` (or one of its friends) from the command line.

/*
TEST(DateTimeColumn_Basic)
{
    DateTimeColumn c;
    c.add(NewDate(123,123));
    NewDate ndt = c.get(0);
    CHECK(ndt == NewDate(123, 123));
}
*/
TEST(DateTimeColumn_Basic_Nulls)
{
    // Test that default value is null() for nullable column and non-null for non-nullable column
    Table t;
    t.add_column(type_NewDate, "date", false /*nullable*/);
    t.add_column(type_NewDate, "date", true  /*nullable*/);

    t.add_empty_row();
    CHECK(!t.is_null(0, 0));
    CHECK(t.is_null(1, 0));

    CHECK_THROW_ANY(t.set_null(0, 0));
    t.set_null(1, 0);
}

TEST(DateTimeColumn_Relocate)
{
    // Fill so much data in a column that it relocates, to check if relocation propagates up correctly
    Table t;
    t.add_column(type_NewDate, "date", true  /*nullable*/);

    for (size_t i = 0; i < 10000; i++) {
        t.add_empty_row();
        t.set_newdate(0, i, NewDate(i, i));
    }
}
#endif // TEST_COLUMN_DATETIME
<commit_msg>Re-enabled the basic unit test for DateTimeColumn.<commit_after>#include "testsettings.hpp"
#ifdef TEST_COLUMN_DATETIME

#include <realm/column_datetime.hpp>
#include <realm.hpp>

#include "test.hpp"

using namespace realm;

// Test independence and thread-safety
// -----------------------------------
//
// All tests must be thread safe and independent of each other. This
// is required because it allows for both shuffling of the execution
// order and for parallelized testing.
//
// In particular, avoid using std::rand() since it is not guaranteed
// to be thread safe. Instead use the API offered in
// `test/util/random.hpp`.
//
// All files created in tests must use the TEST_PATH macro (or one of
// its friends) to obtain a suitable file system path. See
// `test/util/test_path.hpp`.
//
//
// Debugging and the ONLY() macro
// ------------------------------
//
// A simple way of disabling all tests except one called `Foo`, is to
// replace TEST(Foo) with ONLY(Foo) and then recompile and rerun the
// test suite. Note that you can also use filtering by setting the
// environment varible `UNITTEST_FILTER`. See `README.md` for more on
// this.
//
// Another way to debug a particular test, is to copy that test into
// `experiments/testcase.cpp` and then run `sh build.sh
// check-testcase` (or one of its friends) from the command line.

TEST(DateTimeColumn_Basic)
{
    ref_type ref = DateTimeColumn::create(Allocator::get_default());
    DateTimeColumn c(Allocator::get_default(), ref);
    c.add(NewDate(123,123));
    NewDate ndt = c.get(0);
    CHECK(ndt == NewDate(123, 123));
}

TEST(DateTimeColumn_Basic_Nulls)
{
    // Test that default value is null() for nullable column and non-null for non-nullable column
    Table t;
    t.add_column(type_NewDate, "date", false /*nullable*/);
    t.add_column(type_NewDate, "date", true  /*nullable*/);

    t.add_empty_row();
    CHECK(!t.is_null(0, 0));
    CHECK(t.is_null(1, 0));

    CHECK_THROW_ANY(t.set_null(0, 0));
    t.set_null(1, 0);
}

TEST(DateTimeColumn_Relocate)
{
    // Fill so much data in a column that it relocates, to check if relocation propagates up correctly
    Table t;
    t.add_column(type_NewDate, "date", true  /*nullable*/);

    for (size_t i = 0; i < 10000; i++) {
        t.add_empty_row();
        t.set_newdate(0, i, NewDate(i, i));
    }
}
#endif // TEST_COLUMN_DATETIME
<|endoftext|>


<commit_before>#include <QtTest>
#include <QtCore>
#include <QtNetwork>
#include <Arangodbdriver.h>

using namespace arangodb;

/**
 * @brief The StartTest class
 */
class StartTest : public QObject
{
        Q_OBJECT

    public:
        StartTest();

    private Q_SLOTS:
        void initTestCase();
        void cleanupTestCase();
        void testSaveAndDeleteDocument();
        void testSaveDocument2Times();
        void testPartialUpdate();

    private:
        /**
         * @brief waitForDocumentReady
         * @param doc
         */
        inline void waitForDocumentReady(Document* doc) {
            QEventLoop loop;
            connect(doc, &Document::error, &loop, &QEventLoop::quit);
            connect(doc, &Document::ready, &loop, &QEventLoop::quit);
            loop.exec();
        }

        /**
         * @brief waitForDocumentReady
         * @param doc
         */
        inline void waitForDocumentDeleted(Document* doc) {
            QEventLoop loop;
            connect(doc, &Document::error, &loop, &QEventLoop::quit);
            connect(doc, &Document::dataDeleted, &loop, &QEventLoop::quit);
            loop.exec();
        }
};

StartTest::StartTest()
{
}

void StartTest::initTestCase()
{
}

void StartTest::cleanupTestCase()
{
}

/**
 * @brief StartTest::testSaveAndDeleteDocument
 */
void StartTest::testSaveAndDeleteDocument()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    // Set fuu with ss
    doc->set("fuu", QVariant("ss"));
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Check if the flag isCreated is set
    Q_ASSERT_X(doc->isCreated(), "testSaveAndDeleteDocument", doc->errorMessage().toLocal8Bit());

    // Get the same document from the db again
    Document *docFromDb = driver.getDocument(doc->docID());
    waitForDocumentReady(docFromDb);

    // check if there is really the document
    Q_ASSERT_X( !docFromDb->hasErrorOccurred(), "testSaveAndDeleteDocument", docFromDb->errorMessage().toLocal8Bit() );

    QCOMPARE( docFromDb->get("fuu").toString(), QString("ss") );

    // Delete the test document again
    doc->drop();
    waitForDocumentDeleted(doc);

    // Try get the same document from the db again
    docFromDb = driver.getDocument(doc->docID());
    waitForDocumentReady(docFromDb);

    // check if the document doesn't exist anymore
    Q_ASSERT( docFromDb->hasErrorOccurred() );
}

/**
 * @brief StartTest::testSaveDocument2Times
 */
void StartTest::testSaveDocument2Times()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Change the document and save/update
    doc->set("lll", QVariant("aaa"));

    QCOMPARE(doc->dirtyAttributes().size(), 1);
    Q_ASSERT(doc->isEveryAttributeDirty());

    doc->save();
    waitForDocumentReady(doc);

    // check if there wasn't an error
    Q_ASSERT_X( !doc->hasErrorOccurred(), "!doc->hasErrorOccurred()", doc->errorMessage().toLocal8Bit() );

    // Delete the test document again
    doc->drop();
    waitForDocumentDeleted(doc);
}

/**
 * @brief StartTest::testPartialUpdate
 */
void StartTest::testPartialUpdate()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    doc->set("lll", QVariant("aaa"));
    doc->set("dd", QVariant("aaa"));
    doc->set("aa", QVariant("aaa"));
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Change the document and save/update
    doc->set("lll", QVariant("bb"));

    QCOMPARE(doc->dirtyAttributes().size(), 1);
    Q_ASSERT( !doc->isEveryAttributeDirty() );

    doc->save();
    waitForDocumentReady(doc);

    // check if there wasn't an error
    Q_ASSERT_X( !doc->hasErrorOccurred(), "!doc->hasErrorOccurred()", doc->errorMessage().toLocal8Bit() );

    // Delete the test document again
    doc->drop();
    waitForDocumentDeleted(doc);
}

QTEST_MAIN(StartTest)

#include "tst_StartTest.moc"
<commit_msg>Added a test for the status update<commit_after>#include <QtTest>
#include <QtCore>
#include <QtNetwork>
#include <Arangodbdriver.h>

using namespace arangodb;

/**
 * @brief The StartTest class
 */
class StartTest : public QObject
{
        Q_OBJECT

    public:
        StartTest();

    private Q_SLOTS:
        void initTestCase();
        void cleanupTestCase();
        void testSaveAndDeleteDocument();
        void testSaveDocument2Times();
        void testPartialUpdate();
        void testHeadOperation();

    private:
        /**
         * @brief waitForDocumentReady
         * @param doc
         */
        inline void waitForDocumentReady(Document* doc) {
            QEventLoop loop;
            connect(doc, &Document::error, &loop, &QEventLoop::quit);
            connect(doc, &Document::ready, &loop, &QEventLoop::quit);
            loop.exec();
        }

        /**
         * @brief waitForDocumentReady
         * @param doc
         */
        inline void waitForDocumentDeleted(Document* doc) {
            QEventLoop loop;
            connect(doc, &Document::error, &loop, &QEventLoop::quit);
            connect(doc, &Document::dataDeleted, &loop, &QEventLoop::quit);
            loop.exec();
        }
};

StartTest::StartTest()
{
}

void StartTest::initTestCase()
{
}

void StartTest::cleanupTestCase()
{
}

/**
 * @brief StartTest::testSaveAndDeleteDocument
 */
void StartTest::testSaveAndDeleteDocument()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    // Set fuu with ss
    doc->set("fuu", QVariant("ss"));
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Check if the flag isCreated is set
    Q_ASSERT_X(doc->isCreated(), "testSaveAndDeleteDocument", doc->errorMessage().toLocal8Bit());

    // Get the same document from the db again
    Document *docFromDb = driver.getDocument(doc->docID());
    waitForDocumentReady(docFromDb);

    // check if there is really the document
    Q_ASSERT_X( !docFromDb->hasErrorOccurred(), "testSaveAndDeleteDocument", docFromDb->errorMessage().toLocal8Bit() );

    QCOMPARE( docFromDb->get("fuu").toString(), QString("ss") );

    // Delete the test document again
    doc->drop();
    waitForDocumentDeleted(doc);

    // Try get the same document from the db again
    docFromDb = driver.getDocument(doc->docID());
    waitForDocumentReady(docFromDb);

    // check if the document doesn't exist anymore
    Q_ASSERT( docFromDb->hasErrorOccurred() );
}

/**
 * @brief StartTest::testSaveDocument2Times
 */
void StartTest::testSaveDocument2Times()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Change the document and save/update
    doc->set("lll", QVariant("aaa"));

    QCOMPARE(doc->dirtyAttributes().size(), 1);
    Q_ASSERT(doc->isEveryAttributeDirty());

    doc->save();
    waitForDocumentReady(doc);

    // check if there wasn't an error
    Q_ASSERT_X( !doc->hasErrorOccurred(), "!doc->hasErrorOccurred()", doc->errorMessage().toLocal8Bit() );

    // Delete the test document again
    doc->drop();
    waitForDocumentDeleted(doc);
}

/**
 * @brief StartTest::testPartialUpdate
 */
void StartTest::testPartialUpdate()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    doc->set("lll", QVariant("aaa"));
    doc->set("dd", QVariant("aaa"));
    doc->set("aa", QVariant("aaa"));
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Change the document and save/update
    doc->set("lll", QVariant("bb"));

    QCOMPARE(doc->dirtyAttributes().size(), 1);
    Q_ASSERT( !doc->isEveryAttributeDirty() );

    doc->save();
    waitForDocumentReady(doc);

    // check if there wasn't an error
    Q_ASSERT_X( !doc->hasErrorOccurred(), "!doc->hasErrorOccurred()", doc->errorMessage().toLocal8Bit() );

    // Delete the test document again
    doc->drop();
    waitForDocumentDeleted(doc);
}

void StartTest::testHeadOperation()
{
    Arangodbdriver driver;
    Document *doc = driver.createDocument("test");
    doc->set("lll", QVariant("aaa"));
    // Save the document
    doc->save();
    waitForDocumentReady(doc);

    // Try get the same document from the db again
    Document *docFromDb = driver.getDocument(doc->docID());
    waitForDocumentReady(docFromDb);

    docFromDb->updateStatus();
    waitForDocumentReady(docFromDb);

    QCOMPARE( docFromDb->isCreated(), true );
    QCOMPARE( docFromDb->isCurrent(), true );

    doc->set("lllmmmm", "fuu");
    doc->save();
    waitForDocumentReady(doc);

    docFromDb->updateStatus();
    waitForDocumentReady(docFromDb);

    QCOMPARE( docFromDb->isCreated(), true );
    QCOMPARE( docFromDb->isCurrent(), false );

    doc->drop();
    waitForDocumentDeleted(doc);

    docFromDb->updateStatus();
    waitForDocumentReady(docFromDb);

    QCOMPARE( docFromDb->isCreated(), false );
    QCOMPARE( docFromDb->isCurrent(), false );
}

QTEST_MAIN(StartTest)

#include "tst_StartTest.moc"
<|endoftext|>


<commit_before>// window.cpp
#include <QDebug>
#include <QDir>
#include <math.h>

#include "ui_window.h"
#include "window.hpp"

#include "augmentation_widget.hpp"

#ifndef RES_DIR
#define RES_DIR ""
#endif

Window::Window (QWidget* parent)
: QWidget (parent)
, ui (new Ui::Window) {
    _augmentation = new augmentation_widget ();
    _augmentation->show ();
    ui->setupUi (this);

    // fill model selection box
    ui->loadBox->addItem ("Select Model");
    QDir path (":/3D_models/");
    QStringList files = path.entryList (QDir::Files);
    ui->loadBox->addItems (files);

    connect (ui->loadBox, SIGNAL (currentIndexChanged (QString)), this,
    SLOT (loadBox_indexchanged (QString)));
    connect (ui->texButton, SIGNAL (clicked ()), this, SLOT (texButton_clicked ()));

    connect (ui->scaleSlider, SIGNAL (valueChanged (int)), this,
    SLOT (scaleSlider_valueChanged (int)));
    connect (ui->posXSlider, SIGNAL (valueChanged (int)), this,
    SLOT (posXSlider_valueChanged (int)));
    connect (ui->posYSlider, SIGNAL (valueChanged (int)), this,
    SLOT (posYSlider_valueChanged (int)));

    connect (ui->rotXSlider, SIGNAL (valueChanged (int)), this,
    SLOT (rotXSlider_valueChanged (int)));
    connect (ui->rotYSlider, SIGNAL (valueChanged (int)), this,
    SLOT (rotYSlider_valueChanged (int)));
    connect (ui->rotZSlider, SIGNAL (valueChanged (int)), this,
    SLOT (rotZSlider_valueChanged (int)));
}

Window::~Window () {
    delete _augmentation;
    delete ui;
}

void Window::keyPressEvent (QKeyEvent* e) {
    if (e->key () == Qt::Key_Escape)
        close ();
    else
        QWidget::keyPressEvent (e);
}

void Window::loadBox_indexchanged (QString selection) {
    _augmentation->loadObject (selection.prepend (":/3D_models/"));
    _augmentation->update ();
}

void Window::texButton_clicked () {
    QImage image_qt;
    image_t image;

    if (image_qt.load (":/debug_samples/textest.png")) {
        size_t size = image_qt.width () * image_qt.height ();
        image_qt    = image_qt.convertToFormat (QImage::Format_RGB888);
        image.data  = (uint8_t*)malloc (size * 3);
        memcpy (image.data, image_qt.bits (), size * 3);
        image.format = RGB24;
        image.height = image_qt.height ();
        image.width  = image_qt.width ();

        _augmentation->setBackground (image);
    } else {
        qDebug () << "no image";
    }
}

void Window::scaleSlider_valueChanged (int new_value) {
    _augmentation->setScale (((float)new_value) / 100);
    _augmentation->update ();
}
void Window::posXSlider_valueChanged (int new_value) {
    _augmentation->setXPosition (((float)new_value) / 100);
    _augmentation->update ();
}
void Window::posYSlider_valueChanged (int new_value) {
    _augmentation->setYPosition (((float)new_value) / 100);
    _augmentation->update ();
}

void Window::rotXSlider_valueChanged (int new_value) {
    _augmentation->setXRotation (new_value);
    _augmentation->update ();
}
void Window::rotYSlider_valueChanged (int new_value) {
    _augmentation->setYRotation (new_value);
    _augmentation->update ();
}
void Window::rotZSlider_valueChanged (int new_value) {
    _augmentation->setZRotation (new_value);
    _augmentation->update ();
}

/*derived from  https://www.opengl.org/sdk/docs/man2/xhtml/glRotate.xml*/
void Window::angle_to_matrix (float mat[16], float angle, float x, float y, float z) {
    float deg2rad = 3.14159265f / 180.0f;
    float c       = cosf (angle * deg2rad);
    float s       = sinf (angle * deg2rad);
    float c1      = 1.0f - c;

    // build rotation matrix
    mat[0]  = (x * x * c1) + c;
    mat[1]  = (x * y * c1) - (z * s);
    mat[2]  = (x * z * c1) + (y * s);
    mat[3]  = 0;
    mat[4]  = (y * x * c1) + (z * s);
    mat[5]  = (y * y * c1) + c;
    mat[6]  = (y * z * c1) - (x * s);
    mat[7]  = 0;
    mat[8]  = (z * x * c1) - (y * s);
    mat[9]  = (z * y * c1) + (x * s);
    mat[10] = (z * z * c1) + c;
    mat[11] = 0;
    mat[12] = 0;
    mat[13] = 0;
    mat[14] = 0;
    mat[15] = 1;
}
<commit_msg>change test to update after texture change<commit_after>// window.cpp
#include <QDebug>
#include <QDir>
#include <math.h>

#include "ui_window.h"
#include "window.hpp"

#include "augmentation_widget.hpp"

#ifndef RES_DIR
#define RES_DIR ""
#endif

Window::Window (QWidget* parent)
: QWidget (parent)
, ui (new Ui::Window) {
    _augmentation = new augmentation_widget ();
    _augmentation->show ();
    ui->setupUi (this);

    // fill model selection box
    ui->loadBox->addItem ("Select Model");
    QDir path (":/3D_models/");
    QStringList files = path.entryList (QDir::Files);
    ui->loadBox->addItems (files);

    connect (ui->loadBox, SIGNAL (currentIndexChanged (QString)), this,
    SLOT (loadBox_indexchanged (QString)));
    connect (ui->texButton, SIGNAL (clicked ()), this, SLOT (texButton_clicked ()));

    connect (ui->scaleSlider, SIGNAL (valueChanged (int)), this,
    SLOT (scaleSlider_valueChanged (int)));
    connect (ui->posXSlider, SIGNAL (valueChanged (int)), this,
    SLOT (posXSlider_valueChanged (int)));
    connect (ui->posYSlider, SIGNAL (valueChanged (int)), this,
    SLOT (posYSlider_valueChanged (int)));

    connect (ui->rotXSlider, SIGNAL (valueChanged (int)), this,
    SLOT (rotXSlider_valueChanged (int)));
    connect (ui->rotYSlider, SIGNAL (valueChanged (int)), this,
    SLOT (rotYSlider_valueChanged (int)));
    connect (ui->rotZSlider, SIGNAL (valueChanged (int)), this,
    SLOT (rotZSlider_valueChanged (int)));
}

Window::~Window () {
    delete _augmentation;
    delete ui;
}

void Window::keyPressEvent (QKeyEvent* e) {
    if (e->key () == Qt::Key_Escape)
        close ();
    else
        QWidget::keyPressEvent (e);
}

void Window::loadBox_indexchanged (QString selection) {
    _augmentation->loadObject (selection.prepend (":/3D_models/"));
    _augmentation->update ();
}

void Window::texButton_clicked () {
    QImage image_qt;
    image_t image;

    if (image_qt.load (":/debug_samples/textest.png")) {
        size_t size = image_qt.width () * image_qt.height ();
        image_qt    = image_qt.convertToFormat (QImage::Format_RGB888);
        image.data  = (uint8_t*)malloc (size * 3);
        memcpy (image.data, image_qt.bits (), size * 3);
        image.format = RGB24;
        image.height = image_qt.height ();
        image.width  = image_qt.width ();

        _augmentation->setBackground (image);
        _augmentation->update ();
    } else {
        qDebug () << "no image";
    }
}

void Window::scaleSlider_valueChanged (int new_value) {
    _augmentation->setScale (((float)new_value) / 100);
    _augmentation->update ();
}
void Window::posXSlider_valueChanged (int new_value) {
    _augmentation->setXPosition (((float)new_value) / 100);
    _augmentation->update ();
}
void Window::posYSlider_valueChanged (int new_value) {
    _augmentation->setYPosition (((float)new_value) / 100);
    _augmentation->update ();
}

void Window::rotXSlider_valueChanged (int new_value) {
    _augmentation->setXRotation (new_value);
    _augmentation->update ();
}
void Window::rotYSlider_valueChanged (int new_value) {
    _augmentation->setYRotation (new_value);
    _augmentation->update ();
}
void Window::rotZSlider_valueChanged (int new_value) {
    _augmentation->setZRotation (new_value);
    _augmentation->update ();
}

/*derived from  https://www.opengl.org/sdk/docs/man2/xhtml/glRotate.xml*/
void Window::angle_to_matrix (float mat[16], float angle, float x, float y, float z) {
    float deg2rad = 3.14159265f / 180.0f;
    float c       = cosf (angle * deg2rad);
    float s       = sinf (angle * deg2rad);
    float c1      = 1.0f - c;

    // build rotation matrix
    mat[0]  = (x * x * c1) + c;
    mat[1]  = (x * y * c1) - (z * s);
    mat[2]  = (x * z * c1) + (y * s);
    mat[3]  = 0;
    mat[4]  = (y * x * c1) + (z * s);
    mat[5]  = (y * y * c1) + c;
    mat[6]  = (y * z * c1) - (x * s);
    mat[7]  = 0;
    mat[8]  = (z * x * c1) - (y * s);
    mat[9]  = (z * y * c1) + (x * s);
    mat[10] = (z * z * c1) + c;
    mat[11] = 0;
    mat[12] = 0;
    mat[13] = 0;
    mat[14] = 0;
    mat[15] = 1;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "MediaFile.h"
#include <iostream>
#include <string>
#include <algorithm>

#ifdef WIN32

void ConvertPath(std::string &path)
{
  std::replace(path.begin(), path.end(), '/', '\\');
}

#endif

//
// MediaFile
//

MediaFile::MediaFile(std::istream* _stream) : stream(_stream)
{
  // do nothing
}

MediaFile::~MediaFile()
{
  // do nothing
}

bool		MediaFile::isOkay() const
{
  return (stream != NULL && stream->good());
}

void		MediaFile::readRaw(void* vbuffer, uint32_t bytes)
{
  char* buffer = reinterpret_cast<char*>(vbuffer);
  stream->read(buffer, bytes);
}

void		MediaFile::skip(uint32_t bytes)
{
  stream->ignore(bytes);
}

uint16_t	MediaFile::read16LE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16LE(&b);
}

uint16_t	MediaFile::read16BE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16BE(&b);
}

uint32_t	MediaFile::read32LE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32LE(&b);
}

uint32_t	MediaFile::read32BE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32BE(&b);
}

uint16_t	MediaFile::swap16LE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[0]) + (static_cast<uint16_t>(b[1]) << 8);
  return *d;
}

uint16_t	MediaFile::swap16BE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[1]) + (static_cast<uint16_t>(b[0]) << 8);
  return *d;
}

uint32_t	MediaFile::swap32LE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[0]) + (static_cast<uint32_t>(b[1]) << 8) +
       (static_cast<uint32_t>(b[2]) << 16) +
       (static_cast<uint32_t>(b[3]) << 24);
  return *d;
}

uint32_t	MediaFile::swap32BE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[3]) + (static_cast<uint32_t>(b[2]) << 8) +
       (static_cast<uint32_t>(b[1]) << 16) +
       (static_cast<uint32_t>(b[0]) << 24);
  return *d;
}

//
// utility methods to read various media files in any supported format
//

#include "FileManager.h"
#include "SGIImageFile.h"
#include "PNGImageFile.h"
#include "WaveAudioFile.h"

#define OPENMEDIA(_T)					\
do {							\
  stream = FILEMGR.createDataInStream(filename, true);	\
  if (stream == NULL)					\
    stream = FILEMGR.createDataInStream(filename +	\
	     _T::getExtension(), true);			\
  if (stream != NULL) {					\
    file = new _T(stream);				\
    if (!file->isOpen()) {				\
      file = NULL;					\
      delete stream;					\
      stream = NULL;					\
    }							\
  }							\
} while (0)

unsigned char*		MediaFile::readImage(
				std::string filename,
				int* width, int* height)
{
#ifdef WIN32
  // cheat and make sure the file is a windows file path
  ConvertPath(filename);
#endif //WIN32
  // try opening file as an image
  std::istream* stream;
  ImageFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(PNGImageFile);
  if (file == NULL)
    OPENMEDIA(SGIImageFile);

  // read the image
  unsigned char* image = NULL;
  if (file != NULL) {
    // get the image size
    int dx = *width  = file->getWidth();
    int dy = *height = file->getHeight();
    int dz =	   file->getNumChannels();

    // make buffer for final image
    image = new unsigned char[dx * dy * 4];

    // make buffer to read image.  if the image file has 4 channels
    // then read directly into the final image buffer.
    unsigned char* buffer = (dz == 4) ? image : new unsigned char[dx * dy * dz];

    // read the image
    if (image != NULL && buffer != NULL) {
      if (!file->read(buffer)) {
	// failed to read image.  clean up.
	if (buffer != image)
	  delete[] buffer;
	delete[] image;
	image  = NULL;
	buffer = NULL;
      } else {
	// expand image into 4 channels
	int n = dx * dy;
	const unsigned char* src = buffer;
	unsigned char* dst = image;
	if (dz == 1) {
	  // r=g=b=i, a=max
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = 0xff;
	    src += 1;
	    dst += 4;
	  }
	} else if (dz == 2) {
	  // r=g=b=i
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = src[1];
	    src += 2;
	    dst += 4;
	  }
	} else if (dz == 3) {
	  // a=max
	  for (; n > 0; --n) {
	    dst[0] = src[0];
	    dst[1] = src[1];
	    dst[2] = src[2];
	    dst[3] = 0xff;
	    src += 3;
	    dst += 4;
	  }
	}
      }
    }

    // clean up
    if (buffer != image)
      delete[] buffer;
    delete file;
  }

  // clean up
  delete stream;

  return image;
}

/*
float*		MediaFile::readSound(
			const std::string& filename,
			int* _numFrames, int* rate)
{
  // try opening as an audio file
  std::istream* stream;
  AudioFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(WaveAudioFile);

  // read the audio
  float* audio = NULL;
  if (file != NULL) {
    // get the audio info
    *rate	   = file->getFramesPerSecond();
    int numChannels = file->getNumChannels();
    int numFrames   = file->getNumFrames();
    int sampleWidth = file->getSampleWidth();

    // make a buffer to read into
    unsigned char* raw = new unsigned char[numFrames * numChannels * sampleWidth];

    // read raw samples
    if (file->read(raw, numFrames)) {
      // prepare conversion parameters
      int step   = 1;
#if defined(HALF_RATE_AUDIO)
      step      *= 2;
      numFrames /= 2;
      *rate     /= 2;
#endif

      // make final audio buffer
      audio = new float[2 * numFrames];

      // convert
      if (numChannels == 1) {
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = 257.0f * static_cast<float>(*src);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = static_cast<float>(*src);
	    src += step;
	  }
	}
      } else {
	step *= 2;
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = 257.0f * static_cast<float>(src[0]);
	    audio[2 * i + 1] = 257.0f * static_cast<float>(src[1]);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = static_cast<float>(src[0]);
	    audio[2 * i + 1] = static_cast<float>(src[1]);
	    src += step;
	  }
	}
      }
    }

    // clean up
    delete[] raw;
    delete file;
    *_numFrames = numFrames;
  }

  // clean up
  delete stream;

  return audio;
}
*/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>- loadTexture() can now use cached textures from their URL names.   (ex: BZDB _rainTexture and _rainPuddleTexture). These textures   can be signalled for downloading using unbound materials.   Let it rain cats and dogs...<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// implementation header
#include "CacheManager.h"

// system headers
#include <iostream>
#include <string>
#include <algorithm>

// common headers
#include "MediaFile.h"

#ifdef WIN32
void ConvertPath(std::string &path)
{
  std::replace(path.begin(), path.end(), '/', '\\');
}
#endif

//
// MediaFile
//

MediaFile::MediaFile(std::istream* _stream) : stream(_stream)
{
  // do nothing
}

MediaFile::~MediaFile()
{
  // do nothing
}

bool		MediaFile::isOkay() const
{
  return (stream != NULL && stream->good());
}

void		MediaFile::readRaw(void* vbuffer, uint32_t bytes)
{
  char* buffer = reinterpret_cast<char*>(vbuffer);
  stream->read(buffer, bytes);
}

void		MediaFile::skip(uint32_t bytes)
{
  stream->ignore(bytes);
}

uint16_t	MediaFile::read16LE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16LE(&b);
}

uint16_t	MediaFile::read16BE()
{
  uint16_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap16BE(&b);
}

uint32_t	MediaFile::read32LE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32LE(&b);
}

uint32_t	MediaFile::read32BE()
{
  uint32_t b;
  stream->read(reinterpret_cast<char*>(&b), sizeof(b));
  return swap32BE(&b);
}

uint16_t	MediaFile::swap16LE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[0]) + (static_cast<uint16_t>(b[1]) << 8);
  return *d;
}

uint16_t	MediaFile::swap16BE(uint16_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint16_t>(b[1]) + (static_cast<uint16_t>(b[0]) << 8);
  return *d;
}

uint32_t	MediaFile::swap32LE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[0]) + (static_cast<uint32_t>(b[1]) << 8) +
       (static_cast<uint32_t>(b[2]) << 16) +
       (static_cast<uint32_t>(b[3]) << 24);
  return *d;
}

uint32_t	MediaFile::swap32BE(uint32_t* d)
{
  unsigned char* b = reinterpret_cast<unsigned char*>(d);
  *d = static_cast<uint32_t>(b[3]) + (static_cast<uint32_t>(b[2]) << 8) +
       (static_cast<uint32_t>(b[1]) << 16) +
       (static_cast<uint32_t>(b[0]) << 24);
  return *d;
}

//
// utility methods to read various media files in any supported format
//

#include "FileManager.h"
#include "SGIImageFile.h"
#include "PNGImageFile.h"
#include "WaveAudioFile.h"

#define OPENMEDIA(_T)					\
do {							\
  stream = FILEMGR.createDataInStream(filename, true);	\
  if (stream == NULL)					\
    stream = FILEMGR.createDataInStream(filename +	\
	     _T::getExtension(), true);			\
  if (stream != NULL) {					\
    file = new _T(stream);				\
    if (!file->isOpen()) {				\
      file = NULL;					\
      delete stream;					\
      stream = NULL;					\
    }							\
  }							\
} while (0)

unsigned char*		MediaFile::readImage(
				std::string filename,
				int* width, int* height)
{
  // get the absolute filename for cache textures
  if (CACHEMGR.isCacheFileType(filename)) {
    filename = CACHEMGR.getLocalName(filename);
  }
#ifdef WIN32
  // cheat and make sure the file is a windows file path
  ConvertPath(filename);
#endif //WIN32
  // try opening file as an image
  std::istream* stream;
  ImageFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(PNGImageFile);
  if (file == NULL)
    OPENMEDIA(SGIImageFile);

  // read the image
  unsigned char* image = NULL;
  if (file != NULL) {
    // get the image size
    int dx = *width  = file->getWidth();
    int dy = *height = file->getHeight();
    int dz =	   file->getNumChannels();

    // make buffer for final image
    image = new unsigned char[dx * dy * 4];

    // make buffer to read image.  if the image file has 4 channels
    // then read directly into the final image buffer.
    unsigned char* buffer = (dz == 4) ? image : new unsigned char[dx * dy * dz];

    // read the image
    if (image != NULL && buffer != NULL) {
      if (!file->read(buffer)) {
	// failed to read image.  clean up.
	if (buffer != image)
	  delete[] buffer;
	delete[] image;
	image  = NULL;
	buffer = NULL;
      } else {
	// expand image into 4 channels
	int n = dx * dy;
	const unsigned char* src = buffer;
	unsigned char* dst = image;
	if (dz == 1) {
	  // r=g=b=i, a=max
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = 0xff;
	    src += 1;
	    dst += 4;
	  }
	} else if (dz == 2) {
	  // r=g=b=i
	  for (; n > 0; --n) {
	    dst[0] = dst[1] = dst[2] = src[0];
	    dst[3] = src[1];
	    src += 2;
	    dst += 4;
	  }
	} else if (dz == 3) {
	  // a=max
	  for (; n > 0; --n) {
	    dst[0] = src[0];
	    dst[1] = src[1];
	    dst[2] = src[2];
	    dst[3] = 0xff;
	    src += 3;
	    dst += 4;
	  }
	}
      }
    }

    // clean up
    if (buffer != image)
      delete[] buffer;
    delete file;
  }

  // clean up
  delete stream;

  return image;
}

/*
float*		MediaFile::readSound(
			const std::string& filename,
			int* _numFrames, int* rate)
{
  // try opening as an audio file
  std::istream* stream;
  AudioFile* file = NULL;
  if (file == NULL)
    OPENMEDIA(WaveAudioFile);

  // read the audio
  float* audio = NULL;
  if (file != NULL) {
    // get the audio info
    *rate	   = file->getFramesPerSecond();
    int numChannels = file->getNumChannels();
    int numFrames   = file->getNumFrames();
    int sampleWidth = file->getSampleWidth();

    // make a buffer to read into
    unsigned char* raw = new unsigned char[numFrames * numChannels * sampleWidth];

    // read raw samples
    if (file->read(raw, numFrames)) {
      // prepare conversion parameters
      int step   = 1;
#if defined(HALF_RATE_AUDIO)
      step      *= 2;
      numFrames /= 2;
      *rate     /= 2;
#endif

      // make final audio buffer
      audio = new float[2 * numFrames];

      // convert
      if (numChannels == 1) {
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = 257.0f * static_cast<float>(*src);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i] = audio[2 * i + 1] = static_cast<float>(*src);
	    src += step;
	  }
	}
      } else {
	step *= 2;
	if (sampleWidth == 1) {
	  signed char* src = reinterpret_cast<signed char*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = 257.0f * static_cast<float>(src[0]);
	    audio[2 * i + 1] = 257.0f * static_cast<float>(src[1]);
	    src += step;
	  }
	} else {
	  int16_t* src = reinterpret_cast<int16_t*>(raw);
	  for (int i = 0; i < numFrames; ++i) {
	    audio[2 * i]     = static_cast<float>(src[0]);
	    audio[2 * i + 1] = static_cast<float>(src[1]);
	    src += step;
	  }
	}
      }
    }

    // clean up
    delete[] raw;
    delete file;
    *_numFrames = numFrames;
  }

  // clean up
  delete stream;

  return audio;
}
*/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: dinfedt.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: pb $ $Date: 2001-06-28 13:44:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#pragma hdrstop

#include "dinfedt.hxx"
#include "sfxresid.hxx"

#include "sfx.hrc"
#include "dinfedt.hrc"

// class InfoEdit_Impl ---------------------------------------------------

void InfoEdit_Impl::KeyInput( const KeyEvent& rKEvent )
{
    if ( rKEvent.GetCharCode() != '~' )
        Edit::KeyInput( rKEvent );
}

// class SfxDocInfoEditDlg -----------------------------------------------

SfxDocInfoEditDlg::SfxDocInfoEditDlg( Window* pParent ) :

    ModalDialog( pParent, SfxResId( DLG_DOCINFO_EDT ) ),

    aInfoFL     ( this, ResId( FL_INFO ) ),
    aInfo1ED    ( this, ResId( ED_INFO1 ) ),
    aInfo2ED    ( this, ResId( ED_INFO2 ) ),
    aInfo3ED    ( this, ResId( ED_INFO3 ) ),
    aInfo4ED    ( this, ResId( ED_INFO4 ) ),
    aOkBT       ( this, ResId( BT_OK ) ),
    aCancelBT   ( this, ResId( BT_CANCEL ) ),
    aHelpBtn    ( this, ResId( BTN_HELP ) )

{
    FreeResource();
}

<commit_msg>INTEGRATION: CWS ooo20040329 (1.2.464); FILE MERGED 2004/03/18 10:36:43 waratah 1.2.464.1: :#i1858# exclude pragma hdrstop by bracketting for gcc<commit_after>/*************************************************************************
 *
 *  $RCSfile: dinfedt.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: svesik $ $Date: 2004-04-21 13:11:22 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef GCC
#pragma hdrstop
#endif

#include "dinfedt.hxx"
#include "sfxresid.hxx"

#include "sfx.hrc"
#include "dinfedt.hrc"

// class InfoEdit_Impl ---------------------------------------------------

void InfoEdit_Impl::KeyInput( const KeyEvent& rKEvent )
{
    if ( rKEvent.GetCharCode() != '~' )
        Edit::KeyInput( rKEvent );
}

// class SfxDocInfoEditDlg -----------------------------------------------

SfxDocInfoEditDlg::SfxDocInfoEditDlg( Window* pParent ) :

    ModalDialog( pParent, SfxResId( DLG_DOCINFO_EDT ) ),

    aInfoFL     ( this, ResId( FL_INFO ) ),
    aInfo1ED    ( this, ResId( ED_INFO1 ) ),
    aInfo2ED    ( this, ResId( ED_INFO2 ) ),
    aInfo3ED    ( this, ResId( ED_INFO3 ) ),
    aInfo4ED    ( this, ResId( ED_INFO4 ) ),
    aOkBT       ( this, ResId( BT_OK ) ),
    aCancelBT   ( this, ResId( BT_CANCEL ) ),
    aHelpBtn    ( this, ResId( BTN_HELP ) )

{
    FreeResource();
}

<|endoftext|>


<commit_before>//
// Copyright (c) 2019 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include "win_storage_native_target.h"
#include <target_windows_storage_config.h>
#include <nanoHAL_Windows_Storage.h>
#include <target_platform.h>

#include "Esp32_DeviceMapping.h"

// Defines for Windows.Storage.c
extern "C"
{
    bool Storage_InitSDCardSPI(char * vfsName, int maxFiles, int pin_Miso, int pin_Mosi, int pin_Clk, int pin_Cs);
    bool Storage_InitSDCardMMC(char * vfsName, int maxFiles, bool bit1Mode);
    bool Storage_UnMountSDCard();
}

HRESULT Library_win_storage_native_Windows_Storage_Devices_SDCard::MountMMCNative___STATIC__VOID__BOOLEAN(CLR_RT_StackFrame& stack)
{
    NANOCLR_HEADER();

#if defined(HAL_USE_SDC)
    bool bit1Mode = stack.Arg0().NumericByRef().s4;
	char     mountPoint[] = INDEX0_DRIVE_LETTER;

	// Change fatfs drive letter to mount point  D: -> /D
	mountPoint[1] = mountPoint[0];
	mountPoint[0] = '/';

    // Try mounting
    if (!Storage_InitSDCardMMC(mountPoint, SDC_MAX_OPEN_FILES, bit1Mode) )
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND);
    }
#else
    NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
#endif

    NANOCLR_NOCLEANUP();
}

HRESULT Library_win_storage_native_Windows_Storage_Devices_SDCard::MountSpiNative___STATIC__VOID__I4__I4(CLR_RT_StackFrame& stack)
{
    NANOCLR_HEADER();

#if defined(HAL_USE_SDC)

    int      spiBus;
    uint32_t CSPin;
    char     mountPoint[] = INDEX0_DRIVE_LETTER;

	// Change fatfs drive letter to mount point  D: -> /D
	mountPoint[1] = mountPoint[0];
	mountPoint[0] = '/';

    // Get passed SPi bus number
    spiBus = stack.Arg0().NumericByRef().s4;

    // get Gpio pin for Chip select
    CSPin = stack.Arg1().NumericByRef().s4;

    // Get current gpio pins used by SPI device
    int mosiPin =  Esp32_GetMappedDevicePins(DEV_TYPE_SPI, spiBus, 0);
    int misoPin =  Esp32_GetMappedDevicePins(DEV_TYPE_SPI, spiBus, 1);
    int clockPin = Esp32_GetMappedDevicePins(DEV_TYPE_SPI, spiBus, 2);

    // Try mounting
    if ( !Storage_InitSDCardSPI(mountPoint, SDC_MAX_OPEN_FILES, misoPin, mosiPin, clockPin, CSPin) )
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND);
    }
#else
	(void)stack;
    NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
#endif

    NANOCLR_NOCLEANUP();
}

HRESULT Library_win_storage_native_Windows_Storage_Devices_SDCard::UnmountNative___STATIC__VOID(CLR_RT_StackFrame& stack)
{
    NANOCLR_HEADER();
    (void)stack;

#if defined(HAL_USE_SDC)

    // Unmount SPI device
    if (!Storage_UnMountSDCard())
    {
        // SDcard not mounted
        NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION);
    }

#else
    NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
#endif

    NANOCLR_NOCLEANUP();
}
<commit_msg>Spi SDcard fix (#1444)<commit_after>//
// Copyright (c) 2019 The nanoFramework project contributors
// See LICENSE file in the project root for full license information.
//

#include "win_storage_native_target.h"
#include <target_windows_storage_config.h>
#include <nanoHAL_Windows_Storage.h>
#include <target_platform.h>

#include "Esp32_DeviceMapping.h"

// Defines for Windows.Storage.c
extern "C"
{
    bool Storage_InitSDCardSPI(char * vfsName, int maxFiles, int pin_Miso, int pin_Mosi, int pin_Clk, int pin_Cs);
    bool Storage_InitSDCardMMC(char * vfsName, int maxFiles, bool bit1Mode);
    bool Storage_UnMountSDCard();
}

HRESULT Library_win_storage_native_Windows_Storage_Devices_SDCard::MountMMCNative___STATIC__VOID__BOOLEAN(CLR_RT_StackFrame& stack)
{
    NANOCLR_HEADER();

#if defined(HAL_USE_SDC)
    bool bit1Mode = stack.Arg0().NumericByRef().s4;
	char     mountPoint[] = INDEX0_DRIVE_LETTER;

	// Change fatfs drive letter to mount point  D: -> /D
	mountPoint[1] = mountPoint[0];
	mountPoint[0] = '/';

    // Try mounting
    if (!Storage_InitSDCardMMC(mountPoint, SDC_MAX_OPEN_FILES, bit1Mode) )
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND);
    }
#else
    NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
#endif

    NANOCLR_NOCLEANUP();
}

HRESULT Library_win_storage_native_Windows_Storage_Devices_SDCard::MountSpiNative___STATIC__VOID__I4__I4(CLR_RT_StackFrame& stack)
{
    NANOCLR_HEADER();

#if defined(HAL_USE_SDC)

    int      spiBus;
    uint32_t CSPin;
    char     mountPoint[] = INDEX0_DRIVE_LETTER;

	// Change fatfs drive letter to mount point  D: -> /D
	mountPoint[1] = mountPoint[0];
	mountPoint[0] = '/';

    // Get passed SPi bus number 1 or 2
    spiBus = stack.Arg0().NumericByRef().s4;

    // get Gpio pin for Chip select
    CSPin = stack.Arg1().NumericByRef().s4;

    // Get current gpio pins used by SPI device
    spiBus--;  // Spi devnumber 0 & 1
    int mosiPin =  Esp32_GetMappedDevicePins(DEV_TYPE_SPI, spiBus, 0);
    int misoPin =  Esp32_GetMappedDevicePins(DEV_TYPE_SPI, spiBus, 1);
    int clockPin = Esp32_GetMappedDevicePins(DEV_TYPE_SPI, spiBus, 2);

    // Try mounting
    if ( !Storage_InitSDCardSPI(mountPoint, SDC_MAX_OPEN_FILES, misoPin, mosiPin, clockPin, CSPin) )
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND);
    }
#else
	(void)stack;
    NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
#endif

    NANOCLR_NOCLEANUP();
}

HRESULT Library_win_storage_native_Windows_Storage_Devices_SDCard::UnmountNative___STATIC__VOID(CLR_RT_StackFrame& stack)
{
    NANOCLR_HEADER();
    (void)stack;

#if defined(HAL_USE_SDC)

    // Unmount SPI device
    if (!Storage_UnMountSDCard())
    {
        // SDcard not mounted
        NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_OPERATION);
    }

#else
    NANOCLR_SET_AND_LEAVE(stack.NotImplementedStub());
#endif

    NANOCLR_NOCLEANUP();
}
<|endoftext|>


<commit_before>#define FEBIRD_HAS_INHERITING_CONSTRUCTORS
<commit_msg>git rm src/nark/my_auto_config.hpp<commit_after><|endoftext|>