<commit_before>/**
 * @file   llleap_test.cpp
 * @author Nat Goodspeed
 * @date   2012-02-21
 * @brief  Test for llleap.
 *
 * $LicenseInfo:firstyear=2012&license=viewerlgpl$
 * Copyright (c) 2012, Linden Research, Inc.
 * $/LicenseInfo$
 */

// Precompiled header
#include "linden_common.h"
// associated header
#include "llleap.h"
// STL headers
// std headers
// external library headers
#include <boost/assign/list_of.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/foreach.hpp>
// other Linden headers
#include "../test/lltut.h"
#include "../test/namedtempfile.h"
#include "../test/manageapr.h"
#include "../test/catch_and_store_what_in.h"
#include "wrapllerrs.h"
#include "llevents.h"
#include "llprocess.h"
#include "stringize.h"
#include "StringVec.h"

using boost::assign::list_of;

static ManageAPR manager;

StringVec sv(const StringVec& listof) { return listof; }

#if defined(LL_WINDOWS)
#define sleep(secs) _sleep((secs) * 1000)
#endif

void waitfor(const std::vector<LLLeap*>& instances)
{
    int i, timeout = 60;
    for (i = 0; i < timeout; ++i)
    {
        // Every iteration, test whether any of the passed LLLeap instances
        // still exist (are still running).
        std::vector<LLLeap*>::const_iterator vli(instances.begin()), vlend(instances.end());
        for ( ; vli != vlend; ++vli)
        {
            // getInstance() returns NULL if it's terminated/gone, non-NULL if
            // it's still running
            if (LLLeap::getInstance(*vli))
                break;
        }
        // If we made it through all of 'instances' without finding one that's
        // still running, we're done.
        if (vli == vlend)
            return;
        // Found an instance that's still running. Wait and pump LLProcess.
        sleep(1);
        LLEventPumps::instance().obtain("mainloop").post(LLSD());
    }
    tut::ensure("timed out without terminating", i < timeout);
}

void waitfor(LLLeap* instance)
{
    std::vector<LLLeap*> instances;
    instances.push_back(instance);
    waitfor(instances);
}

/*****************************************************************************
*   TUT
*****************************************************************************/
namespace tut
{
    struct llleap_data
    {
        llleap_data():
            reader(".py",
                   // This logic is adapted from vita.viewerclient.receiveEvent()
                   "import sys\n"
                   "LEFTOVER = ''\n"
                   "class ProtocolError(Exception):\n"
                   "    pass\n"
                   "def get():\n"
                   "    global LEFTOVER\n"
                   "    hdr = LEFTOVER\n"
                   "    if ':' not in hdr:\n"
                   "        hdr += sys.stdin.read(20)\n"
                   "        if not hdr:\n"
                   "            sys.exit(0)\n"
                   "    parts = hdr.split(':', 1)\n"
                   "    if len(parts) != 2:\n"
                   "        raise ProtocolError('Expected len:data, got %r' % hdr)\n"
                   "    try:\n"
                   "        length = int(parts[0])\n"
                   "    except ValueError:\n"
                   "        raise ProtocolError('Non-numeric len %r' % parts[0])\n"
                   "    del parts[0]\n"
                   "    received = len(parts[0])\n"
                   "    while received < length:\n"
                   "        parts.append(sys.stdin.read(length - received))\n"
                   "        received += len(parts[-1])\n"
                   "    if received > length:\n"
                   "        excess = length - received\n"
                   "        LEFTOVER = parts[-1][excess:]\n"
                   "        parts[-1] = parts[-1][:excess]\n"
                   "    data = ''.join(parts)\n"
                   "    assert len(data) == length\n"
                   "    return data\n"),
            // Get the actual pathname of the NamedExtTempFile and trim off
            // the ".py" extension. (We could cache reader.getName() in a
            // separate member variable, but I happen to know getName() just
            // returns a NamedExtTempFile member rather than performing any
            // computation, so I don't mind calling it twice.) Then take the
            // basename.
            reader_module(LLProcess::basename(
                              reader.getName().substr(0, reader.getName().length()-3))),
            pPYTHON(getenv("PYTHON")),
            PYTHON(pPYTHON? pPYTHON : "")
        {
            ensure("Set PYTHON to interpreter pathname", pPYTHON);
        }
        NamedExtTempFile reader;
        const std::string reader_module;
        const char* pPYTHON;
        const std::string PYTHON;
    };
    typedef test_group<llleap_data> llleap_group;
    typedef llleap_group::object object;
    llleap_group llleapgrp("llleap");

    template<> template<>
    void object::test<1>()
    {
        set_test_name("multiple LLLeap instances");
        NamedTempFile script("py",
                             "import time\n"
                             "time.sleep(1)\n");
        std::vector<LLLeap*> instances;
        instances.push_back(LLLeap::create(get_test_name(),
                                           sv(list_of(PYTHON)(script.getName()))));
        instances.push_back(LLLeap::create(get_test_name(),
                                           sv(list_of(PYTHON)(script.getName()))));
        // In this case we're simply establishing that two LLLeap instances
        // can coexist without throwing exceptions or bombing in any other
        // way. Wait for them to terminate.
        waitfor(instances);
    }

    template<> template<>
    void object::test<2>()
    {
        set_test_name("stderr to log");
        NamedTempFile script("py",
                             "import sys\n"
                             "sys.stderr.write('''Hello from Python!\n"
                             "note partial line''')\n");
        CaptureLog log(LLError::LEVEL_INFO);
        waitfor(LLLeap::create(get_test_name(),
                               sv(list_of(PYTHON)(script.getName()))));
        log.messageWith("Hello from Python!");
        log.messageWith("note partial line");
    }

    template<> template<>
    void object::test<3>()
    {
        set_test_name("empty plugin vector");
        std::string threw;
        try
        {
            LLLeap::create("empty", StringVec());
        }
        CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error)
        ensure_contains("LLLeap::Error", threw, "no plugin");
        // try the suppress-exception variant
        ensure("bad launch returned non-NULL", ! LLLeap::create("empty", StringVec(), false));
    }

    template<> template<>
    void object::test<4>()
    {
        set_test_name("bad launch");
        // Synthesize bogus executable name
        std::string BADPYTHON(PYTHON.substr(0, PYTHON.length()-1) + "x");
        CaptureLog log;
        std::string threw;
        try
        {
            LLLeap::create("bad exe", BADPYTHON);
        }
        CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error)
        ensure_contains("LLLeap::create() didn't throw", threw, "failed");
        log.messageWith("failed");
        log.messageWith(BADPYTHON);
        // try the suppress-exception variant
        ensure("bad launch returned non-NULL", ! LLLeap::create("bad exe", BADPYTHON, false));
    }

    // Mimic a dummy little LLEventAPI that merely sends a reply back to its
    // requester on the "reply" pump.
    struct API
    {
        API():
            mPump("API", true)
        {
            mPump.listen("API", boost::bind(&API::entry, this, _1));
        }

        bool entry(const LLSD& request)
        {
            LLEventPumps::instance().obtain(request["reply"]).post("ack");
            return false;
        }

        LLEventStream mPump;
    };

    template<> template<>
    void object::test<5>()
    {
        set_test_name("round trip");
        API api;
        NamedTempFile script("py",
                             boost::lambda::_1 <<
                             "import re\n"
                             "import sys\n"
                             "from " << reader_module << " import get\n"
                             // this will throw if the initial write to stdin
                             // doesn't follow len:data protocol
                             "initial = get()\n"
                             "match = re.search(r\"'pump':'(.*?)'\", initial)\n"
                             // this will throw if we couldn't find
                             // 'pump':'etc.' in the initial write
                             "reply = match.group(1)\n"
                             "req = '''\\\n"
                             "{'pump':'" << api.mPump.getName() << "','data':{'reply':'%s'}}\\\n"
                             "''' % reply\n"
                             // make a request on our little API
                             "sys.stdout.write(':'.join((str(len(req)), req)))\n"
                             "sys.stdout.flush()\n"
                             // wait for its response
                             "resp = get()\n"
                             // it would be cleverer to be order-insensitive
                             // about 'data' and 'pump'; hopefully the C++
                             // serializer doesn't change its rules soon
                             "result = 'good' if (resp == \"{'data':'ack','pump':'%s'}\" % reply)\\\n"
                             "                else 'bad: ' + resp\n"
                             // write 'good' or 'bad' to the log so we can observe
                             "sys.stderr.write(result)\n");
        CaptureLog log(LLError::LEVEL_INFO);
        waitfor(LLLeap::create(get_test_name(), sv(list_of(PYTHON)(script.getName()))));
        log.messageWith("good");
    }
} // namespace tut
<commit_msg>Refactor llleap_test.cpp to streamline adding more unit tests. Migrate logic from specific test to common reader module, notably parsing the wakeup message containing the reply-pump name. Make test script post to Result struct to communicate success/failure to C++ TUT test, rather than just writing to log. Make test script insensitive to key order in serialized LLSD::Map.<commit_after>/**
 * @file   llleap_test.cpp
 * @author Nat Goodspeed
 * @date   2012-02-21
 * @brief  Test for llleap.
 *
 * $LicenseInfo:firstyear=2012&license=viewerlgpl$
 * Copyright (c) 2012, Linden Research, Inc.
 * $/LicenseInfo$
 */

// Precompiled header
#include "linden_common.h"
// associated header
#include "llleap.h"
// STL headers
// std headers
// external library headers
#include <boost/assign/list_of.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/foreach.hpp>
// other Linden headers
#include "../test/lltut.h"
#include "../test/namedtempfile.h"
#include "../test/manageapr.h"
#include "../test/catch_and_store_what_in.h"
#include "wrapllerrs.h"
#include "llevents.h"
#include "llprocess.h"
#include "stringize.h"
#include "StringVec.h"

using boost::assign::list_of;

static ManageAPR manager;

StringVec sv(const StringVec& listof) { return listof; }

#if defined(LL_WINDOWS)
#define sleep(secs) _sleep((secs) * 1000)
#endif

void waitfor(const std::vector<LLLeap*>& instances)
{
    int i, timeout = 60;
    for (i = 0; i < timeout; ++i)
    {
        // Every iteration, test whether any of the passed LLLeap instances
        // still exist (are still running).
        std::vector<LLLeap*>::const_iterator vli(instances.begin()), vlend(instances.end());
        for ( ; vli != vlend; ++vli)
        {
            // getInstance() returns NULL if it's terminated/gone, non-NULL if
            // it's still running
            if (LLLeap::getInstance(*vli))
                break;
        }
        // If we made it through all of 'instances' without finding one that's
        // still running, we're done.
        if (vli == vlend)
            return;
        // Found an instance that's still running. Wait and pump LLProcess.
        sleep(1);
        LLEventPumps::instance().obtain("mainloop").post(LLSD());
    }
    tut::ensure("timed out without terminating", i < timeout);
}

void waitfor(LLLeap* instance)
{
    std::vector<LLLeap*> instances;
    instances.push_back(instance);
    waitfor(instances);
}

/*****************************************************************************
*   TUT
*****************************************************************************/
namespace tut
{
    struct llleap_data
    {
        llleap_data():
            reader(".py",
                   // This logic is adapted from vita.viewerclient.receiveEvent()
                   "import re\n"
                   "import sys\n"
                   "LEFTOVER = ''\n"
                   "class ProtocolError(Exception):\n"
                   "    pass\n"
                   "def get():\n"
                   "    global LEFTOVER\n"
                   "    hdr = LEFTOVER\n"
                   "    if ':' not in hdr:\n"
                   "        hdr += sys.stdin.read(20)\n"
                   "        if not hdr:\n"
                   "            sys.exit(0)\n"
                   "    parts = hdr.split(':', 1)\n"
                   "    if len(parts) != 2:\n"
                   "        raise ProtocolError('Expected len:data, got %r' % hdr)\n"
                   "    try:\n"
                   "        length = int(parts[0])\n"
                   "    except ValueError:\n"
                   "        raise ProtocolError('Non-numeric len %r' % parts[0])\n"
                   "    del parts[0]\n"
                   "    received = len(parts[0])\n"
                   "    while received < length:\n"
                   "        parts.append(sys.stdin.read(length - received))\n"
                   "        received += len(parts[-1])\n"
                   "    if received > length:\n"
                   "        excess = length - received\n"
                   "        LEFTOVER = parts[-1][excess:]\n"
                   "        parts[-1] = parts[-1][:excess]\n"
                   "    data = ''.join(parts)\n"
                   "    assert len(data) == length\n"
                   "    return data\n"
                   "\n"
                   "def put(req):\n"
                   "    sys.stdout.write(':'.join((str(len(req)), req)))\n"
                   "    sys.stdout.flush()\n"
                   "\n"
                   "# deal with initial stdin message\n"
                   // this will throw if the initial write to stdin
                   // doesn't follow len:data protocol
                   "_initial = get()\n"
                   "_match = re.search(r\"'pump':'(.*?)'\", _initial)\n"
                   // this will throw if we couldn't find
                   // 'pump':'etc.' in the initial write
                   "_reply = _match.group(1)\n"
                   "\n"
                   "def replypump():\n"
                   "    return _reply\n"
                   "\n"
                   "def escape(str):\n"
                   "    return ''.join(('\\\\'+c if c in r\"\\'\" else c) for c in str)\n"
                   "\n"
                   "def quote(str):\n"
                   "    return \"'%s'\" % escape(str)\n"),
            // Get the actual pathname of the NamedExtTempFile and trim off
            // the ".py" extension. (We could cache reader.getName() in a
            // separate member variable, but I happen to know getName() just
            // returns a NamedExtTempFile member rather than performing any
            // computation, so I don't mind calling it twice.) Then take the
            // basename.
            reader_module(LLProcess::basename(
                              reader.getName().substr(0, reader.getName().length()-3))),
            pPYTHON(getenv("PYTHON")),
            PYTHON(pPYTHON? pPYTHON : "")
        {
            ensure("Set PYTHON to interpreter pathname", pPYTHON);
        }
        NamedExtTempFile reader;
        const std::string reader_module;
        const char* pPYTHON;
        const std::string PYTHON;
    };
    typedef test_group<llleap_data> llleap_group;
    typedef llleap_group::object object;
    llleap_group llleapgrp("llleap");

    template<> template<>
    void object::test<1>()
    {
        set_test_name("multiple LLLeap instances");
        NamedTempFile script("py",
                             "import time\n"
                             "time.sleep(1)\n");
        std::vector<LLLeap*> instances;
        instances.push_back(LLLeap::create(get_test_name(),
                                           sv(list_of(PYTHON)(script.getName()))));
        instances.push_back(LLLeap::create(get_test_name(),
                                           sv(list_of(PYTHON)(script.getName()))));
        // In this case we're simply establishing that two LLLeap instances
        // can coexist without throwing exceptions or bombing in any other
        // way. Wait for them to terminate.
        waitfor(instances);
    }

    template<> template<>
    void object::test<2>()
    {
        set_test_name("stderr to log");
        NamedTempFile script("py",
                             "import sys\n"
                             "sys.stderr.write('''Hello from Python!\n"
                             "note partial line''')\n");
        CaptureLog log(LLError::LEVEL_INFO);
        waitfor(LLLeap::create(get_test_name(),
                               sv(list_of(PYTHON)(script.getName()))));
        log.messageWith("Hello from Python!");
        log.messageWith("note partial line");
    }

    template<> template<>
    void object::test<3>()
    {
        set_test_name("empty plugin vector");
        std::string threw;
        try
        {
            LLLeap::create("empty", StringVec());
        }
        CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error)
        ensure_contains("LLLeap::Error", threw, "no plugin");
        // try the suppress-exception variant
        ensure("bad launch returned non-NULL", ! LLLeap::create("empty", StringVec(), false));
    }

    template<> template<>
    void object::test<4>()
    {
        set_test_name("bad launch");
        // Synthesize bogus executable name
        std::string BADPYTHON(PYTHON.substr(0, PYTHON.length()-1) + "x");
        CaptureLog log;
        std::string threw;
        try
        {
            LLLeap::create("bad exe", BADPYTHON);
        }
        CATCH_AND_STORE_WHAT_IN(threw, LLLeap::Error)
        ensure_contains("LLLeap::create() didn't throw", threw, "failed");
        log.messageWith("failed");
        log.messageWith(BADPYTHON);
        // try the suppress-exception variant
        ensure("bad launch returned non-NULL", ! LLLeap::create("bad exe", BADPYTHON, false));
    }

    // Generic self-contained listener: derive from this and override its
    // call() method, then tell somebody to post on the pump named getName().
    // Control will reach your call() override.
    struct ListenerBase
    {
        // Pass the pump name you want; will tweak for uniqueness.
        ListenerBase(const std::string& name):
            mPump(name, true)
        {
            mPump.listen(name, boost::bind(&ListenerBase::call, this, _1));
        }

        virtual bool call(const LLSD& request)
        {
            return false;
        }

        LLEventPump& getPump() { return mPump; }
        const LLEventPump& getPump() const { return mPump; }

        std::string getName() const { return mPump.getName(); }
        void post(const LLSD& data) { mPump.post(data); }

        LLEventStream mPump;
    };

    // Mimic a dummy little LLEventAPI that merely sends a reply back to its
    // requester on the "reply" pump.
    struct API: public ListenerBase
    {
        API(): ListenerBase("API") {}

        virtual bool call(const LLSD& request)
        {
            LLEventPumps::instance().obtain(request["reply"]).post("ack");
            return false;
        }
    };

    // Give LLLeap script a way to post success/failure.
    struct Result: public ListenerBase
    {
        Result(): ListenerBase("Result") {}

        virtual bool call(const LLSD& request)
        {
            mData = request;
            return false;
        }

        void ensure() const
        {
            tut::ensure(std::string("never posted to ") + getName(), mData.isDefined());
            // Post an empty string for success, non-empty string is failure message.
            tut::ensure(mData, mData.asString().empty());
        }

        LLSD mData;
    };

    template<> template<>
    void object::test<5>()
    {
        set_test_name("round trip");
        API api;
        Result result;
        NamedTempFile script("py",
                             boost::lambda::_1 <<
                             "import sys\n"
                             "from " << reader_module << " import *\n"
                             // make a request on our little API
                             "put(\"{'pump':'" << api.getName() << "','data':{'reply':'%s'}}\" %\n"
                             "    replypump())\n"
                             // wait for its response
                             "resp = get()\n"
                             // We expect "{'data':'ack','pump':'%s'}", but
                             // don't depend on the order of the keys.
                             "result = 'bad: ' + resp\n"
                             "if resp.startswith('{') and resp.endswith('}'):\n"
                             "    expect = set((\"'data':'ack'\", \"'pump':'%s'\" % replypump()))\n"
                             "    actual = set(resp[1:-1].split(','))\n"
                             "    if actual == expect:\n"
                             "        result = ''\n"
                             "put(\"{'pump':'" << result.getName() << "','data':%s}\" %\n"
                             "    quote(result))\n");
        waitfor(LLLeap::create(get_test_name(), sv(list_of(PYTHON)(script.getName()))));
        result.ensure();
    }
} // namespace tut
<|endoftext|>


<commit_before>#include <tiramisu/tiramisu.h>
#include "configure.h"

using namespace tiramisu;

int main(int argc, char **argv)
{
    init("conv_tiramisu");

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------
    var x("x", 0, N), y("y", 0, N), n("n", 0, BATCH_SIZE);
    var k_x("k_x", 0, K), k_y("k_y", 0, K);

    var fin_b("fin_b", 0, FIN_NB_BLOCKS), ffin("ffin", 0, FIN_BLOCKING);
    var fout_b("fout_b", 0, FOUT_NB_BLOCKS), ffout("ffout", 0, FOUT_BLOCKING);

    var x_pad("x_pad", 0, N + 2), y_pad("y_pad", 0, N + 2);

    input c_input("c_input", {n, fin_b, y_pad, x_pad, ffin}, p_float32);
    input filter("filter", {fout_b, fin_b, k_y, k_x, ffin, ffout}, p_float32);
    input bias("bias", {fout_b, ffout}, p_float32);

    computation conv_init("conv_init", {n, y, fout_b, x, ffout}, bias(fout_b, ffout));
    view conv_out("conv_out", {n, y, x, fout_b, ffout}, p_float32);

    // x_bound is used to have the width dimension divisible by X_BLOCKING
    // in the conv computation.
    var x_bound("x_bound", 0, X_BOUND);
    var x_conclude("x_conclude", X_BOUND, N);

    /* Pattern 0
     *
     *   1 1 1
     *   0 0 0
     *   0 0 0
     *
     */
    computation conv_P0(
        "conv_P0",
        {n, y, fin_b, x_bound, ffin, fout_b, ffout},
	((fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL) &&
	((fin_b*FIN_BLOCKING + ffin) <  ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_0_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL),
        conv_out(n, y, x_bound, fout_b, ffout) + filter(fout_b, fin_b, 0, 0, ffin, ffout) * c_input(n, fin_b, y + 0, x_bound + 0, ffin)
					       + filter(fout_b, fin_b, 0, 1, ffin, ffout) * c_input(n, fin_b, y + 0, x_bound + 1, ffin)
					       + filter(fout_b, fin_b, 0, 2, ffin, ffout) * c_input(n, fin_b, y + 0, x_bound + 2, ffin));

    // Compute convolution from 0 to x_bound
    computation conv(
        "conv",
        {n, y, fin_b, x_bound, k_y, k_x, ffin, fout_b, ffout},
	(fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_0_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL,
        conv_out(n, y, x_bound, fout_b, ffout) + filter(fout_b, fin_b, k_y, k_x, ffin, ffout) * c_input(n, fin_b, y + k_y, x_bound + k_x, ffin)
    );

    // Compute convolution from x_bound to N
    computation conv_conclude(
        "conv_conclude",
        {n, y, fin_b, k_y, k_x, ffin, fout_b, ffout, x_conclude},
	(fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL,
        conv_out(n, y, x_conclude, fout_b, ffout) + filter(fout_b, fin_b, k_y, k_x, ffin, ffout) * c_input(n, fin_b, y + k_y, x_conclude + k_x, ffin)
    );

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    // schedule for conv computation

    // We introduce those two computations to do register blocking
    computation reg_load(
        "reg_load",
        {n, y, fin_b, x_bound, fout_b, ffout},
        conv_init(n, y, fout_b, x_bound, ffout)
    );

    computation reg_store(
        "reg_store",
        {n, y, fin_b, x_bound, fout_b, ffout},
        conv(n, y, fin_b, x_bound, 0, 0, 0, fout_b, ffout)
    );

    // Split over dimension x
    var x_b, xx;
    conv.split(x_bound, X_BLOCKING, x_b, xx);
    conv_P0.split(x_bound, X_BLOCKING, x_b, xx);

    conv.interchange(xx, k_y);
    conv.interchange(xx, k_x);
    conv.interchange(xx, ffin);
    conv.interchange(xx, fout_b);
    conv.interchange(xx, ffout);
    conv_P0.interchange(xx, ffin);
    conv_P0.interchange(xx, fout_b);
    conv_P0.interchange(xx, ffout);

    reg_load.split(x_bound, X_BLOCKING, x_b, xx);
    reg_store.split(x_bound, X_BLOCKING, x_b, xx);

    reg_load.interchange(xx, fout_b);
    reg_load.interchange(xx, ffout);

    reg_store.interchange(xx, fout_b);
    reg_store.interchange(xx, ffout);

    // Vectorize and unroll
    reg_load.tag_vector_level(ffout, FOUT_BLOCKING);
    conv.tag_vector_level(ffout, FOUT_BLOCKING);
    conv_P0.tag_vector_level(ffout, FOUT_BLOCKING);
    reg_store.tag_vector_level(ffout, FOUT_BLOCKING);

    conv.tag_unroll_level(xx);
    conv.tag_unroll_level(fout_b);
    conv_P0.tag_unroll_level(xx);
    conv_P0.tag_unroll_level(fout_b);

    reg_load.tag_unroll_level(xx);
    reg_load.tag_unroll_level(fout_b);

    reg_store.tag_unroll_level(xx);
    reg_store.tag_unroll_level(fout_b);

    // schedule for conv_conclude
    // This schedule is the same as conv computation
    computation reg_load_conclude(
        "reg_load_conclude",
        {n, y, fin_b, fout_b, ffout, x_conclude},
        conv_init(n, y, fout_b, x_conclude, ffout)
    );

    computation reg_store_conclude(
        "reg_store_conclude",
        {n, y, fin_b, fout_b, ffout, x_conclude},
        conv_conclude(n, y, fin_b, 0, 0, 0, fout_b, ffout, x_conclude)
    );

    reg_load_conclude.tag_vector_level(ffout, FOUT_BLOCKING);
    conv_conclude.tag_vector_level(ffout, FOUT_BLOCKING);
    reg_store_conclude.tag_vector_level(ffout, FOUT_BLOCKING);

    conv_conclude.tag_unroll_level(x_conclude);
    conv_conclude.tag_unroll_level(fout_b);

    reg_load_conclude.tag_unroll_level(x_conclude);
    reg_load_conclude.tag_unroll_level(fout_b);

    reg_store_conclude.tag_unroll_level(x_conclude);
    reg_store_conclude.tag_unroll_level(fout_b);

    // Parallelize and order
    conv.tag_parallel_level(y);
    conv.tag_parallel_level(n);

    conv_init.then(reg_load, y)
             .then(conv_P0, x_b)
             .then(conv, x_b)
             .then(reg_store, x_b)
             .then(reg_load_conclude, y)
             .then(conv_conclude, fin_b)
             .then(reg_store_conclude, fin_b);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------
    buffer conv_buf("conv_buf", {BATCH_SIZE, FOUT_NB_BLOCKS, N, N, FOUT_BLOCKING}, p_float32, a_output);

    // This is where intermediate results of convolution will be stored.
    // We rely on the compiler to detect that this buffer can be mapped to CPU registers.
    buffer reg_buf("reg_buf", {FOUT_NB_BLOCKS, X_BLOCKING, FOUT_BLOCKING}, p_float32, a_temporary);

    conv_init.store_in(&conv_buf, {n, fout_b, y, x, ffout});
    conv_out.store_in(&reg_buf, {fout_b, x%X_BLOCKING, ffout});

    reg_load.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    conv.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    conv_P0.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    reg_store.store_in(&conv_buf, {n, fout_b, y, x_bound, ffout});

    reg_load_conclude.store_in(&reg_buf, {fout_b, x_conclude%X_BLOCKING, ffout});
    conv_conclude.store_in(&reg_buf, {fout_b, x_conclude%X_BLOCKING, ffout});
    reg_store_conclude.store_in(&conv_buf, {n, fout_b, y, x_conclude, ffout});

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------
    tiramisu::codegen({
        c_input.get_buffer(),
        filter.get_buffer(),
        bias.get_buffer(),
        &conv_buf
    },"generated_conv_layer.o");

    return 0;
}
<commit_msg>Add pattern 1 to sparse_with_dense<commit_after>#include <tiramisu/tiramisu.h>
#include "configure.h"

using namespace tiramisu;

int main(int argc, char **argv)
{
    init("conv_tiramisu");

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------
    var x("x", 0, N), y("y", 0, N), n("n", 0, BATCH_SIZE);
    var k_x("k_x", 0, K), k_y("k_y", 0, K);

    var fin_b("fin_b", 0, FIN_NB_BLOCKS), ffin("ffin", 0, FIN_BLOCKING);
    var fout_b("fout_b", 0, FOUT_NB_BLOCKS), ffout("ffout", 0, FOUT_BLOCKING);

    var x_pad("x_pad", 0, N + 2), y_pad("y_pad", 0, N + 2);

    input c_input("c_input", {n, fin_b, y_pad, x_pad, ffin}, p_float32);
    input filter("filter", {fout_b, fin_b, k_y, k_x, ffin, ffout}, p_float32);
    input bias("bias", {fout_b, ffout}, p_float32);

    computation conv_init("conv_init", {n, y, fout_b, x, ffout}, bias(fout_b, ffout));
    view conv_out("conv_out", {n, y, x, fout_b, ffout}, p_float32);

    // x_bound is used to have the width dimension divisible by X_BLOCKING
    // in the conv computation.
    var x_bound("x_bound", 0, X_BOUND);
    var x_conclude("x_conclude", X_BOUND, N);

    /* Pattern 0
     *
     *   1 1 1
     *   0 0 0
     *   0 0 0
     *
     */
    computation conv_P0(
        "conv_P0",
        {n, y, fin_b, x_bound, ffin, fout_b, ffout},
	((fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL) &&
	((fin_b*FIN_BLOCKING + ffin) <  ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_0_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL),
        conv_out(n, y, x_bound, fout_b, ffout) + filter(fout_b, fin_b, 0, 0, ffin, ffout) * c_input(n, fin_b, y + 0, x_bound + 0, ffin)
					       + filter(fout_b, fin_b, 0, 1, ffin, ffout) * c_input(n, fin_b, y + 0, x_bound + 1, ffin)
					       + filter(fout_b, fin_b, 0, 2, ffin, ffout) * c_input(n, fin_b, y + 0, x_bound + 2, ffin));

    /* Pattern 1
     *
     *   0 0 0
     *   1 1 1
     *   0 0 0
     *
     */
    computation conv_P1(
        "conv_P1",
        {n, y, fin_b, x_bound, ffin, fout_b, ffout},
	((fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_0_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL) &&
	((fin_b*FIN_BLOCKING + ffin) <  ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_0_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL
									       + PATTERN_1_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL),
        conv_out(n, y, x_bound, fout_b, ffout) + filter(fout_b, fin_b, 1, 0, ffin, ffout) * c_input(n, fin_b, y + 1, x_bound + 0, ffin)
					       + filter(fout_b, fin_b, 1, 1, ffin, ffout) * c_input(n, fin_b, y + 1, x_bound + 1, ffin)
					       + filter(fout_b, fin_b, 1, 2, ffin, ffout) * c_input(n, fin_b, y + 1, x_bound + 2, ffin));

    // Compute convolution from 0 to x_bound
    computation conv(
        "conv",
        {n, y, fin_b, x_bound, k_y, k_x, ffin, fout_b, ffout},
	(fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_0_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL + PATTERN_1_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL,
        conv_out(n, y, x_bound, fout_b, ffout) + filter(fout_b, fin_b, k_y, k_x, ffin, ffout) * c_input(n, fin_b, y + k_y, x_bound + k_x, ffin)
    );

    // Compute convolution from x_bound to N
    computation conv_conclude(
        "conv_conclude",
        {n, y, fin_b, k_y, k_x, ffin, fout_b, ffout, x_conclude},
	(fin_b*FIN_BLOCKING + ffin) >= ZERO_WEIGHT_FILTERS_PER_OUTPUT_CHANNEL,
        conv_out(n, y, x_conclude, fout_b, ffout) + filter(fout_b, fin_b, k_y, k_x, ffin, ffout) * c_input(n, fin_b, y + k_y, x_conclude + k_x, ffin)
    );

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    // schedule for conv computation

    // We introduce those two computations to do register blocking
    computation reg_load(
        "reg_load",
        {n, y, fin_b, x_bound, fout_b, ffout},
        conv_init(n, y, fout_b, x_bound, ffout)
    );

    computation reg_store(
        "reg_store",
        {n, y, fin_b, x_bound, fout_b, ffout},
        conv(n, y, fin_b, x_bound, 0, 0, 0, fout_b, ffout)
    );

    // Split over dimension x
    var x_b, xx;
    conv.split(x_bound, X_BLOCKING, x_b, xx);
    conv_P0.split(x_bound, X_BLOCKING, x_b, xx);
    conv_P1.split(x_bound, X_BLOCKING, x_b, xx);

    conv.interchange(xx, k_y);
    conv.interchange(xx, k_x);
    conv.interchange(xx, ffin);
    conv.interchange(xx, fout_b);
    conv.interchange(xx, ffout);
    conv_P0.interchange(xx, ffin);
    conv_P0.interchange(xx, fout_b);
    conv_P0.interchange(xx, ffout);
    conv_P1.interchange(xx, ffin);
    conv_P1.interchange(xx, fout_b);
    conv_P1.interchange(xx, ffout);

    reg_load.split(x_bound, X_BLOCKING, x_b, xx);
    reg_store.split(x_bound, X_BLOCKING, x_b, xx);

    reg_load.interchange(xx, fout_b);
    reg_load.interchange(xx, ffout);

    reg_store.interchange(xx, fout_b);
    reg_store.interchange(xx, ffout);

    // Vectorize and unroll
    reg_load.tag_vector_level(ffout, FOUT_BLOCKING);
    conv.tag_vector_level(ffout, FOUT_BLOCKING);
    conv_P0.tag_vector_level(ffout, FOUT_BLOCKING);
    conv_P1.tag_vector_level(ffout, FOUT_BLOCKING);
    reg_store.tag_vector_level(ffout, FOUT_BLOCKING);

    conv.tag_unroll_level(xx);
    conv.tag_unroll_level(fout_b);
    conv_P0.tag_unroll_level(xx);
    conv_P0.tag_unroll_level(fout_b);
    conv_P1.tag_unroll_level(xx);
    conv_P1.tag_unroll_level(fout_b);

    reg_load.tag_unroll_level(xx);
    reg_load.tag_unroll_level(fout_b);

    reg_store.tag_unroll_level(xx);
    reg_store.tag_unroll_level(fout_b);

    // schedule for conv_conclude
    // This schedule is the same as conv computation
    computation reg_load_conclude(
        "reg_load_conclude",
        {n, y, fin_b, fout_b, ffout, x_conclude},
        conv_init(n, y, fout_b, x_conclude, ffout)
    );

    computation reg_store_conclude(
        "reg_store_conclude",
        {n, y, fin_b, fout_b, ffout, x_conclude},
        conv_conclude(n, y, fin_b, 0, 0, 0, fout_b, ffout, x_conclude)
    );

    reg_load_conclude.tag_vector_level(ffout, FOUT_BLOCKING);
    conv_conclude.tag_vector_level(ffout, FOUT_BLOCKING);
    reg_store_conclude.tag_vector_level(ffout, FOUT_BLOCKING);

    conv_conclude.tag_unroll_level(x_conclude);
    conv_conclude.tag_unroll_level(fout_b);

    reg_load_conclude.tag_unroll_level(x_conclude);
    reg_load_conclude.tag_unroll_level(fout_b);

    reg_store_conclude.tag_unroll_level(x_conclude);
    reg_store_conclude.tag_unroll_level(fout_b);

    // Parallelize and order
    conv.tag_parallel_level(y);
    conv.tag_parallel_level(n);

    conv_init.then(reg_load, y)
             .then(conv_P0, x_b)
             .then(conv_P1, x_b)
             .then(conv, x_b)
             .then(reg_store, x_b)
             .then(reg_load_conclude, y)
             .then(conv_conclude, fin_b)
             .then(reg_store_conclude, fin_b);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------
    buffer conv_buf("conv_buf", {BATCH_SIZE, FOUT_NB_BLOCKS, N, N, FOUT_BLOCKING}, p_float32, a_output);

    // This is where intermediate results of convolution will be stored.
    // We rely on the compiler to detect that this buffer can be mapped to CPU registers.
    buffer reg_buf("reg_buf", {FOUT_NB_BLOCKS, X_BLOCKING, FOUT_BLOCKING}, p_float32, a_temporary);

    conv_init.store_in(&conv_buf, {n, fout_b, y, x, ffout});
    conv_out.store_in(&reg_buf, {fout_b, x%X_BLOCKING, ffout});

    reg_load.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    conv.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    conv_P0.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    conv_P1.store_in(&reg_buf, {fout_b, x_bound%X_BLOCKING, ffout});
    reg_store.store_in(&conv_buf, {n, fout_b, y, x_bound, ffout});

    reg_load_conclude.store_in(&reg_buf, {fout_b, x_conclude%X_BLOCKING, ffout});
    conv_conclude.store_in(&reg_buf, {fout_b, x_conclude%X_BLOCKING, ffout});
    reg_store_conclude.store_in(&conv_buf, {n, fout_b, y, x_conclude, ffout});

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------
    tiramisu::codegen({
        c_input.get_buffer(),
        filter.get_buffer(),
        bias.get_buffer(),
        &conv_buf
    },"generated_conv_layer.o");

    return 0;
}
<|endoftext|>


<commit_before>#include <nds.h>
#include <stdio.h>

#include "panel.h"
#include "ball.h"
#include "stats.h"
#include "game.h"

#define ERR_INIT_SBOX_FAILED 1
#define COLOR_BLACK 0

int main(void) {
    panel player1;
    panel player2;
    ball gameBall;

    scoreBox sBox;
    if(!initScoreBox(&sBox))
        exit(ERR_INIT_SBOX_FAILED);

    int score[2] = {1,2};

    setScore(&sBox, score);

//    consoleDemoInit();
    initGame(&player1, &player2, &gameBall);

	videoSetMode(MODE_FB0);
	vramSetBankA(VRAM_A_LCD);

	printf("%d : %d",sBox.score[0],sBox.score[1]);
	while(1) {
        drawObject(player1.box, COLOR_BLACK);
        drawObject(player2.box, COLOR_BLACK);
        drawObject(gameBall.box, COLOR_BLACK);

        drawObject(player1.box, player1.color);
        drawObject(player2.box, player2.color);
        drawObject(gameBall.box, gameBall.color);

        movePanelOne(&player1, 0);
        movePanelTwo(&player2, 0);

        swiWaitForVBlank();

        //consoleClear();
	}

    return 0;
}
<commit_msg>removed error flag<commit_after>#include <nds.h>
#include <stdio.h>

#include "panel.h"
#include "ball.h"
#include "stats.h"
#include "game.h"

#define COLOR_BLACK 0

int main(void) {
    panel player1;
    panel player2;
    ball gameBall;

    scoreBox sBox;
    if(!initScoreBox(&sBox))
        exit(1);

    int score[2] = {1,2};

    setScore(&sBox, score);

//    consoleDemoInit();
    initGame(&player1, &player2, &gameBall);

	videoSetMode(MODE_FB0);
	vramSetBankA(VRAM_A_LCD);

	printf("%d : %d",sBox.score[0],sBox.score[1]);
	while(1) {
        drawObject(player1.box, COLOR_BLACK);
        drawObject(player2.box, COLOR_BLACK);
        drawObject(gameBall.box, COLOR_BLACK);

        drawObject(player1.box, player1.color);
        drawObject(player2.box, player2.color);
        drawObject(gameBall.box, gameBall.color);

        movePanelOne(&player1, 0);
        movePanelTwo(&player2, 0);

        swiWaitForVBlank();

        //consoleClear();
	}

    return 0;
}
<|endoftext|>


<commit_before>//#define BOOST_ASIO_SEPARATE_COMPILATION

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <iostream>

using namespace std;
using namespace boost::asio;
io_service service;
ip::tcp::socket sock(service);

char buff_read[1024], buff_write[1024] = "ok";
void on_read(const boost::system::error_code &err, std::size_t bytes);
void on_write(const boost::system::error_code &err, std::size_t bytes)
{
	sock.async_read_some(buffer(buff_read), on_read);
}
void on_read(const boost::system::error_code &err, std::size_t bytes)
{
	// ... process the read ...
	sock.async_write_some(buffer(buff_write, 3), on_write);
}
void on_connect(const boost::system::error_code &err)
{
	sock.async_read_some(buffer(buff_read), on_read);
}

/*
  service.run(),         .
    ,  on_connect,      .
   on_connect       (read).
 on_read,  ,     (write).
 on_write,      ,
.    on_write       (read).
,      .
*/
int main(int argc, char* argv[])
{
	setlocale(LC_ALL, "Russian");
	std::cout << "  CLIENT" << endl;
	ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 2001);
	sock.async_connect(ep, on_connect);
	service.run();
}

//      :
/*using boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
io_service service;
ip::tcp::endpoint ep(ip::tcp::v4(), 2001)); // listen on 2001
ip::tcp::acceptor acc(service, ep);
socket_ptr sock(new ip::tcp::socket(service));
start_accept(sock);
service.run();
void start_accept(socket_ptr sock)
{
	acc.async_accept(*sock, boost::bind(handle_accept, sock, _1));
}
void handle_accept(socket_ptr sock, const boost::system::error_code & err)
{
	if (err) return;
	// at this point, you can read/write to the socket
	socket_ptr sock(new ip::tcp::socket(service));
	start_accept(sock);
}*/

//-------------------------------------

 /*,           100 :

bool read = false;
void deadline_handler(const boost::system::error_code &)
{
    std::cout << (read ? "read successfully" : "read failed") << std::endl;
}
void read_handler(const boost::system::error_code &)
{
    read = true;
}
ip::tcp::socket sock(service);

read = false;
char data[512];
sock.async_read_some(buffer(data, 512));
deadline_timer t(service, boost::posix_time::milliseconds(100));
t.async_wait(&deadline_handler);
service.run();
*/

/*
.run()   ,
  ,  service.run()  ,      .
  .      connect_handler,     .
       ,   :
typedef boost::shared_ptr<io_service::work> work_ptr;
work_ptr dummy_work(new io_service::work(service_));

      service_.run()
useservice_.stop()  dummy_work.reset(0); // destroy dummy_work.
*/<commit_msg>udp client<commit_after>// Client
#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#endif

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost::asio;
io_service service;

ip::udp::endpoint ep(ip::address::from_string("127.0.0.1"), 8001);

void sync_echo(std::string msg) {
	ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(), 0));
	sock.send_to(buffer(msg), ep);
	char buff[1024];
	ip::udp::endpoint sender_ep;
	int bytes = sock.receive_from(buffer(buff), sender_ep);
	std::string copy(buff, bytes);
	std::cout << "server echoed our " << msg << ": "
		<< (copy == msg ? "OK" : "FAIL") << std::endl;
	sock.close();
}

int main(int argc, char* argv[]) {
	// connect several clients
	char* messages[] = { "John says hi", "so does James", "Lucy just got home", 0 };
	boost::thread_group threads;
	for (char ** message = messages; *message; ++message) {
		threads.create_thread(boost::bind(sync_echo, *message));
		boost::this_thread::sleep(boost::posix_time::millisec(100));
	}

	threads.join_all();
	//system("pause");
	//return 1;
}

/*#ifdef WIN32
#define _WIN32_WINNT 0x0501
#include <stdio.h>
#endif

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost::asio;
io_service service;

ip::udp::endpoint ep(ip::address::from_string("127.0.0.1"), 8001);

void sync_echo(std::string msg) {
	ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(), 0));
	sock.send_to(buffer(msg), ep);
	char buff[1024];
	ip::udp::endpoint sender_ep;
	int bytes = sock.receive_from(buffer(buff), sender_ep);
	std::string copy(buff, bytes);
	std::cout << "server echoed our " << msg << ": "
		<< (copy == msg ? "OK" : "FAIL") << std::endl;
	sock.close();
}

int main(int argc, char* argv[]) {
	// connect several clients
	char* messages[] = { "John says hi", "so does James", "Lucy just got home", 0 };
	boost::thread_group threads;
	for (char ** message = messages; *message; ++message) {
		threads.create_thread(boost::bind(sync_echo, *message));
		boost::this_thread::sleep(boost::posix_time::millisec(100));
	}
	threads.join_all();
}*/

//#define BOOST_ASIO_SEPARATE_COMPILATION

///-------------------------------------

/*

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <iostream>

using namespace std;
using namespace boost::asio;
io_service service;

void handle_connections()
{
	char buff[1024];
	ip::udp::socket sock(service, ip::udp::endpoint(ip::udp::v4(), 8001));
	while (true)
	{
		ip::udp::endpoint sender_ep;
		int bytes = sock.receive_from(buffer(buff), sender_ep);
		std::string msg(buff, bytes);
		sock.send_to(buffer(msg), sender_ep);
	}
}
int main(int argc, char* argv[])
{
	std::cout << "UDP Server is start" << endl;
	handle_connections();
	return 0;
}

*/

/*
///-------------------------------------///-------------------------------------
struct connection : boost::enable_shared_from_this<connection>
{
	typedef boost::system::error_code error_code;
	typedef boost::shared_ptr<connection> ptr;
	connection() : sock_(service), started_(true) {}
	void start(ip::tcp::endpoint ep)
	{
		sock_.async_connect(ep,
			boost::bind(&connection::on_connect, shared_from_this(), _1));
	}
	void stop()
	{
		if (!started_) return;
		started_ = false;
		sock_.close();
	}
	bool started() { return started_; }
private:
	void on_connect(const error_code & err)
	{
		// here you decide what to do with the connection: read or write
		if (!err) do_read();
		else stop();
	}
	void on_read(const error_code & err, size_t bytes)
	{
		if (!started()) return;
		std::string msg(read_buffer_, bytes);
		if (msg == "can_login")               do_write("access_data");
		else if (msg.find("data ") == 0)    process_data(msg);
		else if (msg == "login_fail")         stop();
	}
	void on_write(const error_code & err, size_t bytes)
	{
		do_read();
	}
	void do_read()
	{
		sock_.async_read_some(buffer(read_buffer_),
			boost::bind(&connection::on_read, shared_from_this(), _1, _2));
	}
	void do_write(const std::string & msg)
	{
		if (!started()) return;
		// note: in case you want to send several messages before
		// doing another async_read, you'll need several write buffers!
		std::copy(msg.begin(), msg.end(), write_buffer_);
		sock_.async_write_some(buffer(write_buffer_, msg.size()),
			boost::bind(&connection::on_write, shared_from_this(), _1, _2));
	}
	void process_data(const std::string & msg)
	{
		// process what comes from server, and then perform another write
	}
private:
	ip::tcp::socket sock_;
	enum { max_msg = 1024 };
	char read_buffer_[max_msg];
	char write_buffer_[max_msg];
	bool started_;
};

int main(int argc, char* argv[])
{
	ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 8001);
	connection::ptr(new connection)->start(ep);
	system("pause");
}*/

///-------------------------------------///-------------------------------------

/*char buff_read[1024], buff_write[1024] = "ok";
void on_read(const boost::system::error_code &err, std::size_t bytes);
void on_write(const boost::system::error_code &err, std::size_t bytes)
{
	sock.async_read_some(buffer(buff_read), on_read);
}
void on_read(const boost::system::error_code &err, std::size_t bytes)
{
	// ... process the read ...
	sock.async_write_some(buffer(buff_write, 3), on_write);
}
void on_connect(const boost::system::error_code &err)
{
	sock.async_read_some(buffer(buff_read), on_read);
}*/

/*
  service.run(),         .
    ,  on_connect,      .
   on_connect       (read).
 on_read,  ,     (write).
 on_write,      ,
.    on_write       (read).
,      .
*/
/*int main(int argc, char* argv[])
{
	setlocale(LC_ALL, "Russian");
	std::cout << "  CLIENT" << endl;
	ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 2001);
	sock.async_connect(ep, on_connect);
	service.run();
}*/

//      :
/*using boost::asio;
typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
io_service service;
ip::tcp::endpoint ep(ip::tcp::v4(), 2001)); // listen on 2001
ip::tcp::acceptor acc(service, ep);
socket_ptr sock(new ip::tcp::socket(service));
start_accept(sock);
service.run();
void start_accept(socket_ptr sock)
{
	acc.async_accept(*sock, boost::bind(handle_accept, sock, _1));
}
void handle_accept(socket_ptr sock, const boost::system::error_code & err)
{
	if (err) return;
	// at this point, you can read/write to the socket
	socket_ptr sock(new ip::tcp::socket(service));
	start_accept(sock);
}*/

//-------------------------------------

 /*,           100 :

bool read = false;
void deadline_handler(const boost::system::error_code &)
{
    std::cout << (read ? "read successfully" : "read failed") << std::endl;
}
void read_handler(const boost::system::error_code &)
{
    read = true;
}
ip::tcp::socket sock(service);

read = false;
char data[512];
sock.async_read_some(buffer(data, 512));
deadline_timer t(service, boost::posix_time::milliseconds(100));
t.async_wait(&deadline_handler);
service.run();
*/

/*
.run()   ,
  ,  service.run()  ,      .
  .      connect_handler,     .
       ,   :
typedef boost::shared_ptr<io_service::work> work_ptr;
work_ptr dummy_work(new io_service::work(service_));

      service_.run()
useservice_.stop()  dummy_work.reset(0); // destroy dummy_work.
*/<|endoftext|>


<commit_before>/**
 * Usage: ./Bat [options]
 *
 * Options:
 *   -h, --help                          Displays this help.
 *   -v, --version                       Displays version information.
 *   -t, --title <title>                 Sets the window title on start.
 *   -s, --size <WxH>                    Sets the BAT window size.
 *   -d, --document <path/to/file.html>  The path to the document you want BAT to
 *                                       load.
 *   -u, --undecorate                    Starts BAT with an undecorated window.
 *   -m, --most                          If TOP is provided, then the window is
 *                                       keept on the top of the other windows. If
 *                                       BOTTOM is provided, the window will be in
 *                                       the behind of all windows.
 *   --debug                             Starts BAT in the debug mode.
 * */
#include <QApplication>
#include "mainwindow.h"
#include <QtWidgets>
#include <QWebFrame>
#include <QWebInspector>

QWebView *webView;
bool debugMode = false;
QStringList applicationArguments;

/*
 *  Javascript API
 * */
class BatJavaScriptOperations : public QObject {
    Q_OBJECT
public:
    /*
     *  Close window
     *  BAT.closeWindow();
     *
     **/
    Q_INVOKABLE void closeWindow () {

        if (debugMode) {
            qDebug() << "[INFO] Closing window.";
        }

        webView->close();
    }

    /*
     *  Resize
     *  BAT.resize(width, height);
     *
     **/
    Q_INVOKABLE void resize (int width, int height) {

        if (debugMode) {
            qDebug() << "[INFO] Resizing window: width=" << width << "px; height=" << height << "px." ;
        }

        webView->resize(width, height);
    }

    /*
     *  Set window flags
     *  BAT.setWindowFlags (type)
     *      - UNDECORATED
     *
     * */
    Q_INVOKABLE void setWindowFlags (QString type) {

        if (debugMode) {
            qDebug() << "[INFO] Setting window flag: " << type;
        }

        QStringList options;
        options << "UNDECORATED"
                << "BOTTOM_MOST"
                << "TOP_MOST"
                << "REMOVE_MINIMIZE"
                << "REMOVE_MAXIMIZE"
                << "REMOVE_CLOSE"
                << "TOOLTIP";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowFlags(Qt::FramelessWindowHint | webView->windowFlags());
                break;
            case 1:
                webView->setWindowFlags(Qt::WindowStaysOnBottomHint | webView->windowFlags());
                break;
            case 2:
                webView->setWindowFlags(Qt::WindowStaysOnTopHint | webView->windowFlags());
                break;
            case 3:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::WindowMinimizeButtonHint);
                break;
            case 4:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::WindowMaximizeButtonHint);
                break;
            case 5:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::WindowCloseButtonHint);
            case 6:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::ToolTip);
                break;
            // TODO Other cases
        }
        webView->show();
    }

    /*
     *  Set window state
     *  BAT.setWindowState (value)
     *      - MAXIMIZED
     *      - MINIMIZED
     *      - FULLSCREEN
     *      - ACTIVE
     * */
    Q_INVOKABLE void setWindowState (QString type) {

        if (debugMode) {
            qDebug() << "[INFO] Setting window state: " << type;
        }

        QStringList options;
        options << "MAXIMIZED" << "MINIMIZED" << "FULLSCREEN" << "ACTIVATE" << "RESTORED";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowState(Qt::WindowMaximized);
                break;
            case 1:
                webView->setWindowState(Qt::WindowMinimized);
                break;
            case 2:
                webView->setWindowState(Qt::WindowFullScreen);
                break;
            case 3:
                webView->setWindowState(Qt::WindowActive);
                break;
            case 4:
                webView->setWindowState(Qt::WindowNoState);
                break;
        }
    }

    /*
     *  Get window size
     *  BAT.getWindowSize ()
     * */
    Q_INVOKABLE QObject *getWindowSize () {

        if (debugMode) {
            qDebug() << "[INFO] Getting the window size.";
        }

        QObject *size = new QObject();
        QSize winSize = webView->size();

        size->setProperty("width", winSize.width());
        size->setProperty("height", winSize.height());

        return size;
    }

    /*
     *  Get screen size
     *  BAT.getScreenSize ()
     *
     * */
    Q_INVOKABLE QObject *getScreenSize () {

        if (debugMode) {
            qDebug() << "[INFO] Getting screen size.";
        }

        QObject *size = new QObject();
        QSize screenSize = qApp->primaryScreen()->size();

        size->setProperty("width", screenSize.width());
        size->setProperty("height", screenSize.height());

        return size;
    }

    /*
     *  Set window position
     *  BAT.setWindowPosition (left, top)
     * */
    Q_INVOKABLE void setWindowPosition (int left, int top) {

        if (debugMode) {
            qDebug() << "[INFO] Setting the window position: left=" << left << "px; top=" << top << "px.";
        }

        webView->move(left, top);
    }

    /*
     *  Get window position
     *  BAT.getWindowPosition (left, top)
     * */
    Q_INVOKABLE QObject *getWindowPosition () {

        if (debugMode) {
            qDebug() << "[INFO] Getting the window position.";
        }

        QObject *position = new QObject();
        QPoint point = webView->pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Get mouse position
     *  BAT.getMousePosition()
     *
     * */
    Q_INVOKABLE QObject *getMousePosition () {

        if (debugMode) {
            qDebug() << "[INFO] Getting the mouse position.";
        }

        QObject *position = new QObject();
        QPoint point = QCursor::pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Set mouse position
     *  BAT.setMousePosition()
     *
     * */
    Q_INVOKABLE void setMousePosition (int x, int y) {

        if (debugMode) {
            qDebug() << "[INFO] Setting the mouse position: x=" << x << "px; y=" << y << "px.";
        }

        QCursor::setPos(x, y);
    }

    /*
     *  Creates a new window
     *  BAT.newWindow(options);
     * */
    // TODO Is this really needed?
    // Q_INVOKABLE void newWindow () {
    //   QWindow newWindow = new QWindow();
    //    newWindow.show();
    // }

    /*
     *  Sets the title of the current window
     *  BAT.setWindowTitle(newTitle)
     *
     * */
    Q_INVOKABLE void setWindowTitle (QString newTitle) {

        if (debugMode) {
            qDebug() << "[INFO] Setting the window title: " << newTitle;
        }

        webView->setWindowTitle(newTitle);
    }

    /*
     *  Writes content to file
     *  BAT.writeFile (path, content);
     *
     * */
    Q_INVOKABLE void writeFile (QString path, QString content) {
        if (debugMode) {
            qDebug() << "[INFO] Writting to file: " << path;
        }

        QFile file(path);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            if (debugMode) {
                qDebug() << "[WARNING] Cannot write file.";
            }
            return;
        }

        QTextStream out(&file);
        out << content;
    }

    /*
     *  Returns the content content of a file
     *  BAT.readFile (path);
     *
     * */
    Q_INVOKABLE QString readFile (QString path) {
        if (debugMode) {
            qDebug() << "[INFO] Reading from file: " << path;
        }

        QFile file(path);
        if(!file.open(QIODevice::ReadOnly)) {
            if (debugMode) {
                qDebug() << "[WARNING] Cannot open file.";
            }
            return "";
        }
        QTextStream in(&file);
        QString fileContent = in.readAll();

        return fileContent;
    }

    /*
     *  Debug
     *  BAT.debug(message)
     *
     * */
    Q_INVOKABLE void debug (QString message) {

        // if (debugMode) {
        //     qDebug() << "[INFO] Printing debug message: " << message;
        // }

        qDebug() << message;
    }

    /*
     *  Insepct element
     *  BAT.inspectElement()
     *
     * */
    Q_INVOKABLE void inspectElement () {

        if (debugMode) {
            qDebug() << "[INFO] Activating inspect element.";
        }

        webView->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);

        QWebInspector inspector;
        inspector.setPage(webView->page());
        inspector.setVisible(true);
    }

    /*
     *  Run bash commands
     *  BAT.debug(command)
     *
     * */
    Q_INVOKABLE QObject *runBash (QString command) {

        if (debugMode) {
            qDebug() << "[INFO] Running bash command: " << command;
        }

        QObject *bashOutput = new QObject();

        QProcess process;
        process.start(command);
        // will wait forever until finished
        process.waitForFinished(-1);

        QString stdout = process.readAllStandardOutput();
        QString stderr = process.readAllStandardError();

        bashOutput->setProperty("stdout", stdout);
        bashOutput->setProperty("stderr", stderr);

        return bashOutput;
    }

    /*
     *  Get application arguments
     *  BAT.argv()
     *
     * */
    Q_INVOKABLE QStringList argv () {

        if (debugMode) {
            qDebug() << "[INFO] Getting application arguments.";
        }

        return applicationArguments;
    }

    /*
     *  Enable/Disable debug mode
     *  BAT.setDebugMode(true/false)
     *
     * */
    Q_INVOKABLE void setDebugMode (bool debug) {

        if (debugMode) {
            qDebug() << "[INFO] Setting debug mode: " << debug;
        }

        debugMode = debug;
    }

    /*
     *  Get debug mode
     *  BAT.getDebugMode(true/false)
     *
     * */
    Q_INVOKABLE bool getDebugMode () {

        if (debugMode) {
            qDebug() << "[INFO] Getting debug mode.";
        }

        return debugMode;
    }

    /*
     *  Get dirname
     *  BAT.getDirname()
     *
     * */
    Q_INVOKABLE QString getDirname () {

        if (debugMode) {
            qDebug() << "[INFO] Getting directory name.";
        }

        return QDir::current().absolutePath();
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWebView *view = new QWebView();

    // Local storage
    QWebSettings *settings = view->settings();
    settings->setAttribute(QWebSettings::LocalStorageEnabled, true);
    settings->setLocalStoragePath("/tmp");

    QCoreApplication::setApplicationName("BAT");
    QCoreApplication::setApplicationVersion("1.1.0");

    // Defaults
    int WINDOW_WIDTH = 800;
    int WINDOW_HEIGHT = 600;

    // Save arguments
    applicationArguments = app.arguments();

    // Parse command line arguments
    QCommandLineParser parser;
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption titleOption(QStringList() << "t" << "title", "Sets the window title on start.", "title", "BAT");
    parser.addOption(titleOption);

    QCommandLineOption sizeOption(QStringList() << "s" << "size", "Sets the BAT window size.", "WxH", QString::number(WINDOW_WIDTH) + "x" + QString::number(WINDOW_HEIGHT));
    parser.addOption(sizeOption);

    QCommandLineOption sourceOption(QStringList() << "d" << "document", "The path to the document you want BAT to load.", "path/to/file.html", "~/.bat/welcome.html");
    parser.addOption(sourceOption);

    QCommandLineOption undecorateOption(QStringList() << "u" << "undecorate", "Starts BAT with an undecorated window.");
    parser.addOption(undecorateOption);

    QCommandLineOption toolTipOption(QStringList() << "t" << "tooltip", "Starts BAT with a tooltip window.");
    parser.addOption(toolTipOption);

    QCommandLineOption positionMost(QStringList() << "m" << "most", "If TOP is provided, then the window is keept on the top of the other windows. If BOTTOM is provided, the window will be in the behind of all windows.");
    parser.addOption(positionMost);

    QCommandLineOption debugOption("debug", QCoreApplication::translate("main", "Starts BAT in the debug mode."));
    parser.addOption(debugOption);

    parser.process(app);

    // Set the webview global
    webView = view;

    // Get the HTML path
    QString htmlPath = parser.value(sourceOption);

    // Handle local files
    if (!htmlPath.startsWith("http"))
    {
        // Absolute path
        if (htmlPath.startsWith("/")) {
            htmlPath = "file://" + htmlPath;
        } else if (htmlPath.startsWith("~")) {
            htmlPath = "file://" + htmlPath.replace(QRegularExpression("^~"), QDir::homePath());
        } else {
            htmlPath = "file://" + QDir::current().absolutePath() + QDir::separator() + htmlPath;
        }
    }

    QString size = parser.value(sizeOption);

    // Get window width and height
    int windowWidth = size.split('x')[0].toInt();
    int windowHeight = size.split('x')[1].toInt();

    // Handle "UNDECORATED" flag
    if (parser.isSet(undecorateOption)) {
        QPalette pal = view->palette();
        pal.setBrush(QPalette::Base, Qt::transparent);
        view->page()->setPalette(pal);
        view->setAttribute(Qt::WA_TranslucentBackground);
        view->setWindowFlags(Qt::FramelessWindowHint | view->windowFlags());
    }

    // Tool tip
    if (parser.isSet(toolTipOption)) {
        view->setWindowFlags(Qt::ToolTip | view->windowFlags());
    }

    // Handle the debug mode
    if (parser.isSet(debugOption)) {
        qDebug() << " * Debug mode.";
        debugMode = true;
        view->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
        QWebInspector inspector;
        inspector.setPage(view->page());
        inspector.setVisible(true);
    }

    QString btMost = parser.value(positionMost);
    if (btMost == "BOTTOM") {
        view->setWindowFlags(Qt::WindowStaysOnBottomHint | view->windowFlags());
    } else if (btMost == "TOP") {
        view->setWindowFlags(Qt::WindowStaysOnTopHint    | view->windowFlags());
    }

    // Add the JavaScript API
    view->page()->mainFrame()->addToJavaScriptWindowObject("BAT", new BatJavaScriptOperations);

    view->resize(windowWidth, windowHeight);
    view->load(QUrl(htmlPath));
    view->show();

    webView->setWindowTitle(parser.value(titleOption));
    return app.exec();
}

#include "main.moc"
<commit_msg>Fixed t conflict.<commit_after>/**
 * Usage: ./Bat [options]
 *
 * Options:
 *   -h, --help                          Displays this help.
 *   -v, --version                       Displays version information.
 *   -t, --title <title>                 Sets the window title on start.
 *   -s, --size <WxH>                    Sets the BAT window size.
 *   -d, --document <path/to/file.html>  The path to the document you want BAT to
 *                                       load.
 *   -u, --undecorate                    Starts BAT with an undecorated window.
 *   -m, --most                          If TOP is provided, then the window is
 *                                       keept on the top of the other windows. If
 *                                       BOTTOM is provided, the window will be in
 *                                       the behind of all windows.
 *   --debug                             Starts BAT in the debug mode.
 * */
#include <QApplication>
#include "mainwindow.h"
#include <QtWidgets>
#include <QWebFrame>
#include <QWebInspector>

QWebView *webView;
bool debugMode = false;
QStringList applicationArguments;

/*
 *  Javascript API
 * */
class BatJavaScriptOperations : public QObject {
    Q_OBJECT
public:
    /*
     *  Close window
     *  BAT.closeWindow();
     *
     **/
    Q_INVOKABLE void closeWindow () {

        if (debugMode) {
            qDebug() << "[INFO] Closing window.";
        }

        webView->close();
    }

    /*
     *  Resize
     *  BAT.resize(width, height);
     *
     **/
    Q_INVOKABLE void resize (int width, int height) {

        if (debugMode) {
            qDebug() << "[INFO] Resizing window: width=" << width << "px; height=" << height << "px." ;
        }

        webView->resize(width, height);
    }

    /*
     *  Set window flags
     *  BAT.setWindowFlags (type)
     *      - UNDECORATED
     *
     * */
    Q_INVOKABLE void setWindowFlags (QString type) {

        if (debugMode) {
            qDebug() << "[INFO] Setting window flag: " << type;
        }

        QStringList options;
        options << "UNDECORATED"
                << "BOTTOM_MOST"
                << "TOP_MOST"
                << "REMOVE_MINIMIZE"
                << "REMOVE_MAXIMIZE"
                << "REMOVE_CLOSE"
                << "TOOLTIP";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowFlags(Qt::FramelessWindowHint | webView->windowFlags());
                break;
            case 1:
                webView->setWindowFlags(Qt::WindowStaysOnBottomHint | webView->windowFlags());
                break;
            case 2:
                webView->setWindowFlags(Qt::WindowStaysOnTopHint | webView->windowFlags());
                break;
            case 3:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::WindowMinimizeButtonHint);
                break;
            case 4:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::WindowMaximizeButtonHint);
                break;
            case 5:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::WindowCloseButtonHint);
            case 6:
                webView->setWindowFlags(webView->windowFlags() & ~Qt::ToolTip);
                break;
            // TODO Other cases
        }
        webView->show();
    }

    /*
     *  Set window state
     *  BAT.setWindowState (value)
     *      - MAXIMIZED
     *      - MINIMIZED
     *      - FULLSCREEN
     *      - ACTIVE
     * */
    Q_INVOKABLE void setWindowState (QString type) {

        if (debugMode) {
            qDebug() << "[INFO] Setting window state: " << type;
        }

        QStringList options;
        options << "MAXIMIZED" << "MINIMIZED" << "FULLSCREEN" << "ACTIVATE" << "RESTORED";

        switch (options.indexOf(type)) {
            case 0:
                webView->setWindowState(Qt::WindowMaximized);
                break;
            case 1:
                webView->setWindowState(Qt::WindowMinimized);
                break;
            case 2:
                webView->setWindowState(Qt::WindowFullScreen);
                break;
            case 3:
                webView->setWindowState(Qt::WindowActive);
                break;
            case 4:
                webView->setWindowState(Qt::WindowNoState);
                break;
        }
    }

    /*
     *  Get window size
     *  BAT.getWindowSize ()
     * */
    Q_INVOKABLE QObject *getWindowSize () {

        if (debugMode) {
            qDebug() << "[INFO] Getting the window size.";
        }

        QObject *size = new QObject();
        QSize winSize = webView->size();

        size->setProperty("width", winSize.width());
        size->setProperty("height", winSize.height());

        return size;
    }

    /*
     *  Get screen size
     *  BAT.getScreenSize ()
     *
     * */
    Q_INVOKABLE QObject *getScreenSize () {

        if (debugMode) {
            qDebug() << "[INFO] Getting screen size.";
        }

        QObject *size = new QObject();
        QSize screenSize = qApp->primaryScreen()->size();

        size->setProperty("width", screenSize.width());
        size->setProperty("height", screenSize.height());

        return size;
    }

    /*
     *  Set window position
     *  BAT.setWindowPosition (left, top)
     * */
    Q_INVOKABLE void setWindowPosition (int left, int top) {

        if (debugMode) {
            qDebug() << "[INFO] Setting the window position: left=" << left << "px; top=" << top << "px.";
        }

        webView->move(left, top);
    }

    /*
     *  Get window position
     *  BAT.getWindowPosition (left, top)
     * */
    Q_INVOKABLE QObject *getWindowPosition () {

        if (debugMode) {
            qDebug() << "[INFO] Getting the window position.";
        }

        QObject *position = new QObject();
        QPoint point = webView->pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Get mouse position
     *  BAT.getMousePosition()
     *
     * */
    Q_INVOKABLE QObject *getMousePosition () {

        if (debugMode) {
            qDebug() << "[INFO] Getting the mouse position.";
        }

        QObject *position = new QObject();
        QPoint point = QCursor::pos();

        position->setProperty("left", point.x());
        position->setProperty("top", point.y());

        return position;
    }

    /*
     *  Set mouse position
     *  BAT.setMousePosition()
     *
     * */
    Q_INVOKABLE void setMousePosition (int x, int y) {

        if (debugMode) {
            qDebug() << "[INFO] Setting the mouse position: x=" << x << "px; y=" << y << "px.";
        }

        QCursor::setPos(x, y);
    }

    /*
     *  Creates a new window
     *  BAT.newWindow(options);
     * */
    // TODO Is this really needed?
    // Q_INVOKABLE void newWindow () {
    //   QWindow newWindow = new QWindow();
    //    newWindow.show();
    // }

    /*
     *  Sets the title of the current window
     *  BAT.setWindowTitle(newTitle)
     *
     * */
    Q_INVOKABLE void setWindowTitle (QString newTitle) {

        if (debugMode) {
            qDebug() << "[INFO] Setting the window title: " << newTitle;
        }

        webView->setWindowTitle(newTitle);
    }

    /*
     *  Writes content to file
     *  BAT.writeFile (path, content);
     *
     * */
    Q_INVOKABLE void writeFile (QString path, QString content) {
        if (debugMode) {
            qDebug() << "[INFO] Writting to file: " << path;
        }

        QFile file(path);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            if (debugMode) {
                qDebug() << "[WARNING] Cannot write file.";
            }
            return;
        }

        QTextStream out(&file);
        out << content;
    }

    /*
     *  Returns the content content of a file
     *  BAT.readFile (path);
     *
     * */
    Q_INVOKABLE QString readFile (QString path) {
        if (debugMode) {
            qDebug() << "[INFO] Reading from file: " << path;
        }

        QFile file(path);
        if(!file.open(QIODevice::ReadOnly)) {
            if (debugMode) {
                qDebug() << "[WARNING] Cannot open file.";
            }
            return "";
        }
        QTextStream in(&file);
        QString fileContent = in.readAll();

        return fileContent;
    }

    /*
     *  Debug
     *  BAT.debug(message)
     *
     * */
    Q_INVOKABLE void debug (QString message) {

        // if (debugMode) {
        //     qDebug() << "[INFO] Printing debug message: " << message;
        // }

        qDebug() << message;
    }

    /*
     *  Insepct element
     *  BAT.inspectElement()
     *
     * */
    Q_INVOKABLE void inspectElement () {

        if (debugMode) {
            qDebug() << "[INFO] Activating inspect element.";
        }

        webView->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);

        QWebInspector inspector;
        inspector.setPage(webView->page());
        inspector.setVisible(true);
    }

    /*
     *  Run bash commands
     *  BAT.debug(command)
     *
     * */
    Q_INVOKABLE QObject *runBash (QString command) {

        if (debugMode) {
            qDebug() << "[INFO] Running bash command: " << command;
        }

        QObject *bashOutput = new QObject();

        QProcess process;
        process.start(command);
        // will wait forever until finished
        process.waitForFinished(-1);

        QString stdout = process.readAllStandardOutput();
        QString stderr = process.readAllStandardError();

        bashOutput->setProperty("stdout", stdout);
        bashOutput->setProperty("stderr", stderr);

        return bashOutput;
    }

    /*
     *  Get application arguments
     *  BAT.argv()
     *
     * */
    Q_INVOKABLE QStringList argv () {

        if (debugMode) {
            qDebug() << "[INFO] Getting application arguments.";
        }

        return applicationArguments;
    }

    /*
     *  Enable/Disable debug mode
     *  BAT.setDebugMode(true/false)
     *
     * */
    Q_INVOKABLE void setDebugMode (bool debug) {

        if (debugMode) {
            qDebug() << "[INFO] Setting debug mode: " << debug;
        }

        debugMode = debug;
    }

    /*
     *  Get debug mode
     *  BAT.getDebugMode(true/false)
     *
     * */
    Q_INVOKABLE bool getDebugMode () {

        if (debugMode) {
            qDebug() << "[INFO] Getting debug mode.";
        }

        return debugMode;
    }

    /*
     *  Get dirname
     *  BAT.getDirname()
     *
     * */
    Q_INVOKABLE QString getDirname () {

        if (debugMode) {
            qDebug() << "[INFO] Getting directory name.";
        }

        return QDir::current().absolutePath();
    }
};

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    QWebView *view = new QWebView();

    // Local storage
    QWebSettings *settings = view->settings();
    settings->setAttribute(QWebSettings::LocalStorageEnabled, true);
    settings->setLocalStoragePath("/tmp");

    QCoreApplication::setApplicationName("BAT");
    QCoreApplication::setApplicationVersion("1.1.0");

    // Defaults
    int WINDOW_WIDTH = 800;
    int WINDOW_HEIGHT = 600;

    // Save arguments
    applicationArguments = app.arguments();

    // Parse command line arguments
    QCommandLineParser parser;
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption titleOption(QStringList() << "t" << "title", "Sets the window title on start.", "title", "BAT");
    parser.addOption(titleOption);

    QCommandLineOption sizeOption(QStringList() << "s" << "size", "Sets the BAT window size.", "WxH", QString::number(WINDOW_WIDTH) + "x" + QString::number(WINDOW_HEIGHT));
    parser.addOption(sizeOption);

    QCommandLineOption sourceOption(QStringList() << "d" << "document", "The path to the document you want BAT to load.", "path/to/file.html", "~/.bat/welcome.html");
    parser.addOption(sourceOption);

    QCommandLineOption undecorateOption(QStringList() << "u" << "undecorate", "Starts BAT with an undecorated window.");
    parser.addOption(undecorateOption);

    QCommandLineOption toolTipOption(QStringList() << "tt" << "tooltip", "Starts BAT with a tooltip window.");
    parser.addOption(toolTipOption);

    QCommandLineOption positionMost(QStringList() << "m" << "most", "If TOP is provided, then the window is keept on the top of the other windows. If BOTTOM is provided, the window will be in the behind of all windows.");
    parser.addOption(positionMost);

    QCommandLineOption debugOption("debug", QCoreApplication::translate("main", "Starts BAT in the debug mode."));
    parser.addOption(debugOption);

    parser.process(app);

    // Set the webview global
    webView = view;

    // Get the HTML path
    QString htmlPath = parser.value(sourceOption);

    // Handle local files
    if (!htmlPath.startsWith("http"))
    {
        // Absolute path
        if (htmlPath.startsWith("/")) {
            htmlPath = "file://" + htmlPath;
        } else if (htmlPath.startsWith("~")) {
            htmlPath = "file://" + htmlPath.replace(QRegularExpression("^~"), QDir::homePath());
        } else {
            htmlPath = "file://" + QDir::current().absolutePath() + QDir::separator() + htmlPath;
        }
    }

    QString size = parser.value(sizeOption);

    // Get window width and height
    int windowWidth = size.split('x')[0].toInt();
    int windowHeight = size.split('x')[1].toInt();

    // Handle "UNDECORATED" flag
    if (parser.isSet(undecorateOption)) {
        QPalette pal = view->palette();
        pal.setBrush(QPalette::Base, Qt::transparent);
        view->page()->setPalette(pal);
        view->setAttribute(Qt::WA_TranslucentBackground);
        view->setWindowFlags(Qt::FramelessWindowHint | view->windowFlags());
    }

    // Tool tip
    if (parser.isSet(toolTipOption)) {
        view->setWindowFlags(Qt::ToolTip | view->windowFlags());
    }

    // Handle the debug mode
    if (parser.isSet(debugOption)) {
        qDebug() << " * Debug mode.";
        debugMode = true;
        view->page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
        QWebInspector inspector;
        inspector.setPage(view->page());
        inspector.setVisible(true);
    }

    QString btMost = parser.value(positionMost);
    if (btMost == "BOTTOM") {
        view->setWindowFlags(Qt::WindowStaysOnBottomHint | view->windowFlags());
    } else if (btMost == "TOP") {
        view->setWindowFlags(Qt::WindowStaysOnTopHint    | view->windowFlags());
    }

    // Add the JavaScript API
    view->page()->mainFrame()->addToJavaScriptWindowObject("BAT", new BatJavaScriptOperations);

    view->resize(windowWidth, windowHeight);
    view->load(QUrl(htmlPath));
    view->show();

    webView->setWindowTitle(parser.value(titleOption));
    return app.exec();
}

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


<commit_before>//-----------------------------------------------------------------------------
// Copyright (c) 2015, Jeff Hutchinson
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of D3D11Test nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include <stdlib.h>
#include <SDL.h>

// SDL2 hack.
#ifdef main
#undef main
#endif // main

// Require MSVC compiler for this application
#ifndef _MSC_VER
#error "You must use MSVC to compile this application."
#endif // _MSC_VER

int main(int argc, const char **argv) {
	SDL_Init(SDL_INIT_VIDEO);

	SDL_Event event;
	bool running = true;
	while (running) {
		// Run event loop.
		while (SDL_PollEvent(&event)) {
			// check to see if we fired a quit event. If we did, we're done
			// running the program.
			if (event.type == SDL_QUIT) {
				running = false;
				break;
			}
		}
	}

	SDL_Quit();
	return 0;
}<commit_msg>create a window<commit_after>//-----------------------------------------------------------------------------
// Copyright (c) 2015, Jeff Hutchinson
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// * Neither the name of D3D11Test nor the names of its
//   contributors may be used to endorse or promote products derived from
//   this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//-----------------------------------------------------------------------------

#include <stdlib.h>
#include <SDL.h>

// SDL2 hack.
#ifdef main
#undef main
#endif // main

// Require MSVC compiler for this application
#ifndef _MSC_VER
#error "You must use MSVC to compile this application."
#endif // _MSC_VER

int main(int argc, const char **argv) {
	SDL_Init(SDL_INIT_VIDEO);

	// create window
	SDL_Window *window = SDL_CreateWindow("D3D11 Test Application", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1366, 768, SDL_WINDOW_SHOWN);
	if (window == nullptr) {
		SDL_Quit();
		return 1;
	}

	SDL_Event event;
	bool running = true;
	while (running) {
		// Run event loop.
		while (SDL_PollEvent(&event)) {
			// check to see if we fired a quit event. If we did, we're done
			// running the program.
			if (event.type == SDL_QUIT) {
				running = false;
				break;
			}
		}
	}

	SDL_Quit();
	return 0;
}<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstdio>

int getparam (std::string input) {
  if(input.size() <= 3) { return -1;}
  int result = 0;
  for (int i = 3; i < input.size(); i++) {
    if ( input[i] < '0' || input[i] > '9') { return -2; }
    result = result * 10;
    result += input[i] - '0';
  }
  return result;
}

std::string getstringparam(std::string input) {
  std::string result;
  for (int i = 3; i < input.size(); i++) {
    result.push_back(input[i]);
  }
  return result;
}

void readpreset( unsigned int values[], std::string & filename ) {
  std::ifstream presetfile ("preset");
  presetfile >> filename;
  for (int i = 0; i < 9; i++ ) { presetfile >> values[i]; }
  presetfile.close();
}

void writepreset( unsigned int values[], std::string filename ) {
  std::ofstream presetfile ("preset");
  presetfile << filename;
  for (int i = 0; i < 9; i++ ) {
    presetfile << values[i];
    presetfile << "\n";
  }
  presetfile.close();
}

void writesh( unsigned int values[], std::string filename ) {
  std::ofstream shfile ("run.sh");
  shfile << "ffmpeg -i " << filename << " -f flv -re ";
  if (values[0] != 0 && values[1] != 0) { shfile << "-s " << values[0] << "x" << values[1] << " "; }
  if (values[2] != 0) { shfile << "-b " <<   values[2] << " "; }
  if (values[3] != 0) { shfile << "-gop " << values[3] << " "; }
  if (values[4] != 0) { shfile << "-r " <<   values[4] << " "; }
  if (values[5] != 0) { shfile << "-ab " <<  values[5] << " "; }
  if (values[6] != 0) { shfile << "-ar " <<  values[6] << " "; }
  shfile << "rtmp://projectlivestream.com/oflaDemo/test";
  shfile.close();
}

int main() {
  unsigned int values[9];
  std::string inputcommand = "";
  bool connection = true;
  int tempresult;
  std::string filename = "";
  readpreset(values, filename);
  while (connection) {
    std::cin >> inputcommand;
    switch (inputcommand[0]) {
      case 'G':
        switch (inputcommand[1]) {
          case 'S':
            switch(inputcommand[2]) {
              case 'H': std::cout << "OK" << values[0] << "\n"; break;
              case 'W': std::cout << "OK" << values[1] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'V':
            switch(inputcommand[2]) {
              case 'B': std::cout << "OK" << values[2] << "\n"; break;
              case 'G': std::cout << "OK" << values[3] << "\n"; break;
              case 'R': std::cout << "OK" << values[4] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'A':
            switch(inputcommand[2]) {
              case 'B': std::cout << "OK" << values[5] << "\n"; break;
              case 'R': std::cout << "OK" << values[6] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'U':
            switch(inputcommand[2]) {
              case 'F': std::cout << "OK" << values[7] << "\n"; break;
              case 'P': std::cout << "OK" << values[8] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'F':
            switch(inputcommand[2]) {
              case 'N': std::cout << "OK" << filename << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          default: std::cout << "ER\n"; break;
        }
        break;
      case 'S':
        switch (inputcommand[1]) {
          case 'S':
            switch(inputcommand[2]) {
              case 'H':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[0] = tempresult; std::cout << "OK\n"; }
                break;
              case 'W':
                tempresult = getparam(inputcommand);
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[1] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'V':
            switch(inputcommand[2]) {
              case 'B':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[2] = tempresult; std::cout << "OK\n"; }
                break;
              case 'G':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[3] = tempresult; std::cout << "OK\n"; }
                break;
              case 'R':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[4] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'A':
            switch(inputcommand[2]) {
              case 'B':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[5] = tempresult; std::cout << "OK\n"; }
                break;
              case 'R':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[6] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'U':
            switch(inputcommand[2]) {
              case 'F':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[7] = tempresult; std::cout << "OK\n"; }
                break;
              case 'P':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[8] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'F':
            switch(inputcommand[2]) {
              case 'N':
                filename = getstringparam(inputcommand); std::cout << "OK\n";
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          default: std::cout << "ER\n"; break;
        }
        break;
      case 'C':
        switch (inputcommand[1] ) {
          case 'C':
            switch (inputcommand[2]) {
              case 'D': std::cout << "OK\n"; connection = false; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'S':
            switch (inputcommand[2]) {
              case 'R': std::cout << "OK\n"; readpreset(values, filename); break;
              case 'S': std::cout << "OK\n"; writepreset(values, filename); break;
              case 'A': std::cout << "OK\n"; writesh(values, filename); break;
              default: std::cout << "ER\n"; break;
            }
            break;
          default: std::cout << "ER\n"; break;
        }
        break;
      default: std::cout << "ER\n"; break;
    }
  }
  return 0;
}

<commit_msg>Daadwerkelijke restarten werkend en getest<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <stdlib.h>

int getparam (std::string input) {
  if(input.size() <= 3) { return -1;}
  int result = 0;
  for (int i = 3; i < input.size(); i++) {
    if ( input[i] < '0' || input[i] > '9') { return -2; }
    result = result * 10;
    result += input[i] - '0';
  }
  return result;
}

std::string getstringparam(std::string input) {
  std::string result;
  for (int i = 3; i < input.size(); i++) {
    result.push_back(input[i]);
  }
  return result;
}

void readpreset( unsigned int values[], std::string & filename ) {
  std::ifstream presetfile ("preset");
  presetfile >> filename;
  for (int i = 0; i < 9; i++ ) { presetfile >> values[i]; }
  presetfile.close();
}

void writepreset( unsigned int values[], std::string filename ) {
  std::ofstream presetfile ("preset");
  presetfile << filename;
  for (int i = 0; i < 9; i++ ) {
    presetfile << values[i];
    presetfile << "\n";
  }
  presetfile.close();
}

void writesh( unsigned int values[], std::string filename ) {
  std::ofstream shfile ("run.sh");
  shfile << "ffmpeg -i " << filename << " -f flv -re ";
  if (values[0] != 0 && values[1] != 0) { shfile << "-s " << values[0] << "x" << values[1] << " "; }
  if (values[2] != 0) { shfile << "-b " <<   values[2] << " "; }
  if (values[3] != 0) { shfile << "-gop " << values[3] << " "; }
  if (values[4] != 0) { shfile << "-r " <<   values[4] << " "; }
  if (values[5] != 0) { shfile << "-ab " <<  values[5] << " "; }
  if (values[6] != 0) { shfile << "-ar " <<  values[6] << " "; }
  shfile << "rtmp://projectlivestream.com/oflaDemo/test &";
  shfile.close();
  system("sh ./run.sh");
}

int main() {
  unsigned int values[9];
  std::string inputcommand = "";
  bool connection = true;
  int tempresult;
  std::string filename = "";
  readpreset(values, filename);
  while (connection) {
    std::cin >> inputcommand;
    switch (inputcommand[0]) {
      case 'G':
        switch (inputcommand[1]) {
          case 'S':
            switch(inputcommand[2]) {
              case 'H': std::cout << "OK" << values[0] << "\n"; break;
              case 'W': std::cout << "OK" << values[1] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'V':
            switch(inputcommand[2]) {
              case 'B': std::cout << "OK" << values[2] << "\n"; break;
              case 'G': std::cout << "OK" << values[3] << "\n"; break;
              case 'R': std::cout << "OK" << values[4] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'A':
            switch(inputcommand[2]) {
              case 'B': std::cout << "OK" << values[5] << "\n"; break;
              case 'R': std::cout << "OK" << values[6] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'U':
            switch(inputcommand[2]) {
              case 'F': std::cout << "OK" << values[7] << "\n"; break;
              case 'P': std::cout << "OK" << values[8] << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'F':
            switch(inputcommand[2]) {
              case 'N': std::cout << "OK" << filename << "\n"; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          default: std::cout << "ER\n"; break;
        }
        break;
      case 'S':
        switch (inputcommand[1]) {
          case 'S':
            switch(inputcommand[2]) {
              case 'H':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[0] = tempresult; std::cout << "OK\n"; }
                break;
              case 'W':
                tempresult = getparam(inputcommand);
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[1] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'V':
            switch(inputcommand[2]) {
              case 'B':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[2] = tempresult; std::cout << "OK\n"; }
                break;
              case 'G':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[3] = tempresult; std::cout << "OK\n"; }
                break;
              case 'R':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[4] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'A':
            switch(inputcommand[2]) {
              case 'B':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[5] = tempresult; std::cout << "OK\n"; }
                break;
              case 'R':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[6] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'U':
            switch(inputcommand[2]) {
              case 'F':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[7] = tempresult; std::cout << "OK\n"; }
                break;
              case 'P':
                tempresult = getparam(inputcommand);
                if (tempresult < 0) { std::cout << "ER\n"; } else { values[8] = tempresult; std::cout << "OK\n"; }
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'F':
            switch(inputcommand[2]) {
              case 'N':
                filename = getstringparam(inputcommand); std::cout << "OK\n";
                break;
              default: std::cout << "ER\n"; break;
            }
            break;
          default: std::cout << "ER\n"; break;
        }
        break;
      case 'C':
        switch (inputcommand[1] ) {
          case 'C':
            switch (inputcommand[2]) {
              case 'D': std::cout << "OK\n"; connection = false; break;
              default: std::cout << "ER\n"; break;
            }
            break;
          case 'S':
            switch (inputcommand[2]) {
              case 'R': std::cout << "OK\n"; readpreset(values, filename); break;
              case 'S': std::cout << "OK\n"; writepreset(values, filename); break;
              case 'A': std::cout << "OK\n"; writesh(values, filename); break;
              default: std::cout << "ER\n"; break;
            }
            break;
          default: std::cout << "ER\n"; break;
        }
        break;
      default: std::cout << "ER\n"; break;
    }
  }
  return 0;
}

<|endoftext|>