<commit_before>#include "CacheTable.h"

#define default_cache_size 10

/***
 * Constructs a cache which takes and returns data encapsulated as pointers to TupleRow or PyObject
 * Follows Least Recently Used replacement strategy
 * @param size Max elements the cache will hold, afterwards replacement takes place
 * @param table Name of the table being represented
 * @param keyspace Name of the keyspace whose table belongs to
 * @param query Query ready to be bind with the keys
 * @param session
 */
CacheTable::CacheTable(const TableMetadata *table_meta, CassSession *session,
                       std::map<std::string, std::string> &config) {

    if (!session)
        throw ModuleException("CacheTable: Session is Null");

    int32_t cache_size = default_cache_size;

    if (config.find("cache_size") != config.end()) {
        std::string cache_size_str = config["cache_size"];
        try {
            cache_size = std::stoi(cache_size_str);
            if (cache_size < 0) throw ModuleException("Cache size value must be >= 0");
        }
        catch (std::exception &e) {
            std::string msg(e.what());
            msg += " Malformed value in config for cache_size";
            throw ModuleException(msg);
        }
    }

    /** Parse names **/

    CassFuture *future = cass_session_prepare(session, table_meta->get_select_query());
    CassError rc = cass_future_error_code(future);
    CHECK_CASS("CacheTable: Select row query preparation failed");
    this->prepared_query = cass_future_get_prepared(future);
    cass_future_free(future);
    future = cass_session_prepare(session, table_meta->get_delete_query());
    rc = cass_future_error_code(future);
    this->delete_query = cass_future_get_prepared(future);
    CHECK_CASS("CacheTable: Delete row query preparation failed");
    cass_future_free(future);
    this->myCache = NULL;
    this->session = session;
    this->table_metadata = table_meta;
    this->writer = new Writer(table_meta, session, config);
    this->keys_factory = new TupleRowFactory(table_meta->get_keys());
    this->values_factory = new TupleRowFactory(table_meta->get_values());
    if (cache_size) this->myCache = new TupleRowCache<TupleRow, TupleRow>(cache_size);
};

CacheTable::~CacheTable() {
    delete (writer);
    if (myCache) {
        //stl tree calls deallocate for cache nodes on clear()->erase(), and later on destroy, which ends up calling the deleters
        myCache->clear();
        delete (myCache);
    }
    delete (keys_factory);
    delete (values_factory);
    if (prepared_query != NULL) cass_prepared_free(prepared_query);
    prepared_query = NULL;
    if (delete_query != NULL) cass_prepared_free(delete_query);
    delete_query = NULL;
    delete (table_metadata);
}

void CacheTable::put_crow(const TupleRow *keys, const TupleRow *values) {
    this->writer->write_to_cassandra(keys, values);
    if (myCache) this->myCache->update(*keys, values); //Inserts if not present, otherwise replaces
}

void CacheTable::put_crow(void *keys, void *values) {
    const TupleRow *k = keys_factory->make_tuple(keys);
    const TupleRow *v = values_factory->make_tuple(values);
    this->put_crow(k, v);
    delete (k);
    delete (v);
}

/** this method only adds the data to the cache
 *  without making it persistent
 * @param keys
 * @param values
 */

void CacheTable::add_to_cache(void *keys, void *values) {
    const TupleRow *k = keys_factory->make_tuple(keys);
    const TupleRow *v = values_factory->make_tuple(values);
    if (myCache) this->myCache->update(*k, v);
    delete (k);
    delete (v);
}

void CacheTable::put_crow(const TupleRow *row) {
    //split into two and call put_crow(a,b);
    std::shared_ptr<const std::vector<ColumnMeta> > keys_meta = keys_factory->get_metadata();
    uint16_t nkeys = (uint16_t) keys_meta->size();
    std::shared_ptr<const std::vector<ColumnMeta> > values_meta = values_factory->get_metadata();
    uint16_t nvalues = (uint16_t) values_meta->size();

    char *keys = (char *) malloc(
            keys_meta->at(nkeys - (uint16_t) 1).position + keys_meta->at(nkeys - (uint16_t) 1).size);
    char *values = (char *) malloc(
            values_meta->at(nvalues - (uint16_t) 1).position + values_meta->at(nvalues - (uint16_t) 1).size);
    TupleRow *k = keys_factory->make_tuple(keys);
    TupleRow *v = values_factory->make_tuple(values);
    //Copy keys
    for (uint16_t i = 0; i < nkeys; ++i) {
        CassValueType type = keys_meta->at(i).type;
        const void *element_i = row->get_element(i);
        if (element_i != nullptr) {
            if (type == CASS_VALUE_TYPE_BLOB) {
                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t *size = (uint64_t *) from_data;

                void *new_data = malloc(*size);
                memcpy(new_data, from_data, *size + sizeof(uint64_t));
                //Copy ptr
                memcpy(keys + keys_meta->at(i).position, &new_data, keys_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_TEXT || type == CASS_VALUE_TYPE_VARCHAR ||
                       type == CASS_VALUE_TYPE_ASCII) {

                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t size = strlen(from_data);

                void *new_data = malloc(size);
                memcpy(new_data, from_data, size);
                //Copy ptr
                memcpy(keys + keys_meta->at(i).position, &new_data, keys_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_UUID) {

                uint64_t **from = (uint64_t **) element_i;

                uint64_t size = sizeof(uint64_t) * 2;
                void *new_data = malloc(size);
                memcpy(new_data, *from, size);
                //Copy ptr
                memcpy(keys + keys_meta->at(i).position, &new_data, keys_meta->at(i).size);
            } else memcpy(keys + keys_meta->at(i).position, element_i, keys_meta->at(i).size);
        } else k->setNull(i);
    }

    //Copy values
    for (uint16_t i = 0; i < nvalues; ++i) {

        CassValueType type = values_meta->at(i).type;
        const void *element_i = row->get_element(i + nkeys);
        if (element_i != nullptr) {
            if (type == CASS_VALUE_TYPE_BLOB) {
                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t *size = (uint64_t *) from_data;

                void *new_data = malloc(*size);
                memcpy(new_data, from_data, *size + sizeof(uint64_t));
                //Copy ptr
                memcpy(values + values_meta->at(i).position, &new_data, values_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_TEXT || type == CASS_VALUE_TYPE_VARCHAR ||
                       type == CASS_VALUE_TYPE_ASCII) {

                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t size = strlen(from_data);

                void *new_data = malloc(size);
                memcpy(new_data, from_data, size);
                //Copy ptr
                memcpy(values + values_meta->at(i).position, &new_data, values_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_UUID) {

                uint64_t **from = (uint64_t **) element_i;

                uint64_t size = sizeof(uint64_t) * 2;
                void *new_data = malloc(size);
                memcpy(new_data, *from, size);
                //Copy ptr
                memcpy(values + values_meta->at(i).position, &new_data, values_meta->at(i).size);
            } else memcpy(values + values_meta->at(i).position, element_i, values_meta->at(i).size);
        } else v->setNull(i);
    }
    this->add_to_cache(keys, values);
}

/*
 * POST: never returns NULL
 */
std::vector<const TupleRow *> CacheTable::retrieve_from_cassandra(const TupleRow *keys) {

    /* Not present on cache, a query is performed */
    CassStatement *statement = cass_prepared_bind(prepared_query);

    this->keys_factory->bind(statement, keys, 0);

    CassFuture *query_future = cass_session_execute(session, statement);
    const CassResult *result = cass_future_get_result(query_future);
    CassError rc = cass_future_error_code(query_future);
    if (result == NULL) {
        /* Handle error */
        std::string error(cass_error_desc(rc));
        cass_future_free(query_future);
        cass_statement_free(statement);
        throw ModuleException("CacheTable: Get row error on result" + error);
    }

    cass_future_free(query_future);
    cass_statement_free(statement);

    uint32_t counter = 0;
    std::vector<const TupleRow *> values(cass_result_row_count(result));

    const CassRow *row;
    CassIterator *it = cass_iterator_from_result(result);
    while (cass_iterator_next(it)) {
        row = cass_iterator_get_row(it);
        values[counter] = values_factory->make_tuple(row);
        ++counter;
    }
    cass_iterator_free(it);
    cass_result_free(result);
    return values;
}

std::vector<const TupleRow *> CacheTable::get_crow(const TupleRow *keys) {
    if (myCache) {
        Poco::SharedPtr<TupleRow> ptrElem = myCache->get(*keys);
        if (!ptrElem.isNull()) return std::vector<const TupleRow *> {new TupleRow(ptrElem.get())};
    }

    std::vector<const TupleRow *> values = retrieve_from_cassandra(keys);

    if (myCache && !values.empty()) myCache->add(*keys, values[0]);

    return values;
}

std::vector<const TupleRow *> CacheTable::get_crow(void *keys) {
    const TupleRow *tuple_key = keys_factory->make_tuple(keys);
    std::vector<const TupleRow *> result = get_crow(tuple_key);
    delete (tuple_key);
    return result;
}

void CacheTable::delete_crow(const TupleRow *keys) {

    //Remove row from Cassandra
    CassStatement *statement = cass_prepared_bind(delete_query);

    this->keys_factory->bind(statement, keys, 0);

    CassFuture *query_future = cass_session_execute(session, statement);
    const CassResult *result = cass_future_get_result(query_future);
    CassError rc = cass_future_error_code(query_future);
    if (result == NULL) {
        /* Handle error */
        std::string error(cass_error_desc(rc));
        cass_future_free(query_future);
        cass_statement_free(statement);
        throw ModuleException("CacheTable: Delete row error on result" + error);
    }

    cass_future_free(query_future);
    cass_statement_free(statement);
    cass_result_free(result);

    //Remove entry from cache
    if (myCache) myCache->Remove(*keys);
}<commit_msg>Default the cache to 0 because of #153<commit_after>#include "CacheTable.h"

#define default_cache_size 0

/***
 * Constructs a cache which takes and returns data encapsulated as pointers to TupleRow or PyObject
 * Follows Least Recently Used replacement strategy
 * @param size Max elements the cache will hold, afterwards replacement takes place
 * @param table Name of the table being represented
 * @param keyspace Name of the keyspace whose table belongs to
 * @param query Query ready to be bind with the keys
 * @param session
 */
CacheTable::CacheTable(const TableMetadata *table_meta, CassSession *session,
                       std::map<std::string, std::string> &config) {

    if (!session)
        throw ModuleException("CacheTable: Session is Null");

    int32_t cache_size = default_cache_size;

    if (config.find("cache_size") != config.end()) {
        std::string cache_size_str = config["cache_size"];
        try {
            cache_size = std::stoi(cache_size_str);
            if (cache_size < 0) throw ModuleException("Cache size value must be >= 0");
        }
        catch (std::exception &e) {
            std::string msg(e.what());
            msg += " Malformed value in config for cache_size";
            throw ModuleException(msg);
        }
    }

    /** Parse names **/

    CassFuture *future = cass_session_prepare(session, table_meta->get_select_query());
    CassError rc = cass_future_error_code(future);
    CHECK_CASS("CacheTable: Select row query preparation failed");
    this->prepared_query = cass_future_get_prepared(future);
    cass_future_free(future);
    future = cass_session_prepare(session, table_meta->get_delete_query());
    rc = cass_future_error_code(future);
    this->delete_query = cass_future_get_prepared(future);
    CHECK_CASS("CacheTable: Delete row query preparation failed");
    cass_future_free(future);
    this->myCache = NULL;
    this->session = session;
    this->table_metadata = table_meta;
    this->writer = new Writer(table_meta, session, config);
    this->keys_factory = new TupleRowFactory(table_meta->get_keys());
    this->values_factory = new TupleRowFactory(table_meta->get_values());
    if (cache_size) this->myCache = new TupleRowCache<TupleRow, TupleRow>(cache_size);
};

CacheTable::~CacheTable() {
    delete (writer);
    if (myCache) {
        //stl tree calls deallocate for cache nodes on clear()->erase(), and later on destroy, which ends up calling the deleters
        myCache->clear();
        delete (myCache);
    }
    delete (keys_factory);
    delete (values_factory);
    if (prepared_query != NULL) cass_prepared_free(prepared_query);
    prepared_query = NULL;
    if (delete_query != NULL) cass_prepared_free(delete_query);
    delete_query = NULL;
    delete (table_metadata);
}

void CacheTable::put_crow(const TupleRow *keys, const TupleRow *values) {
    this->writer->write_to_cassandra(keys, values);
    if (myCache) this->myCache->update(*keys, values); //Inserts if not present, otherwise replaces
}

void CacheTable::put_crow(void *keys, void *values) {
    const TupleRow *k = keys_factory->make_tuple(keys);
    const TupleRow *v = values_factory->make_tuple(values);
    this->put_crow(k, v);
    delete (k);
    delete (v);
}

/** this method only adds the data to the cache
 *  without making it persistent
 * @param keys
 * @param values
 */

void CacheTable::add_to_cache(void *keys, void *values) {
    const TupleRow *k = keys_factory->make_tuple(keys);
    const TupleRow *v = values_factory->make_tuple(values);
    if (myCache) this->myCache->update(*k, v);
    delete (k);
    delete (v);
}

void CacheTable::put_crow(const TupleRow *row) {
    //split into two and call put_crow(a,b);
    std::shared_ptr<const std::vector<ColumnMeta> > keys_meta = keys_factory->get_metadata();
    uint16_t nkeys = (uint16_t) keys_meta->size();
    std::shared_ptr<const std::vector<ColumnMeta> > values_meta = values_factory->get_metadata();
    uint16_t nvalues = (uint16_t) values_meta->size();

    char *keys = (char *) malloc(
            keys_meta->at(nkeys - (uint16_t) 1).position + keys_meta->at(nkeys - (uint16_t) 1).size);
    char *values = (char *) malloc(
            values_meta->at(nvalues - (uint16_t) 1).position + values_meta->at(nvalues - (uint16_t) 1).size);
    TupleRow *k = keys_factory->make_tuple(keys);
    TupleRow *v = values_factory->make_tuple(values);
    //Copy keys
    for (uint16_t i = 0; i < nkeys; ++i) {
        CassValueType type = keys_meta->at(i).type;
        const void *element_i = row->get_element(i);
        if (element_i != nullptr) {
            if (type == CASS_VALUE_TYPE_BLOB) {
                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t *size = (uint64_t *) from_data;

                void *new_data = malloc(*size);
                memcpy(new_data, from_data, *size + sizeof(uint64_t));
                //Copy ptr
                memcpy(keys + keys_meta->at(i).position, &new_data, keys_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_TEXT || type == CASS_VALUE_TYPE_VARCHAR ||
                       type == CASS_VALUE_TYPE_ASCII) {

                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t size = strlen(from_data);

                void *new_data = malloc(size);
                memcpy(new_data, from_data, size);
                //Copy ptr
                memcpy(keys + keys_meta->at(i).position, &new_data, keys_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_UUID) {

                uint64_t **from = (uint64_t **) element_i;

                uint64_t size = sizeof(uint64_t) * 2;
                void *new_data = malloc(size);
                memcpy(new_data, *from, size);
                //Copy ptr
                memcpy(keys + keys_meta->at(i).position, &new_data, keys_meta->at(i).size);
            } else memcpy(keys + keys_meta->at(i).position, element_i, keys_meta->at(i).size);
        } else k->setNull(i);
    }

    //Copy values
    for (uint16_t i = 0; i < nvalues; ++i) {

        CassValueType type = values_meta->at(i).type;
        const void *element_i = row->get_element(i + nkeys);
        if (element_i != nullptr) {
            if (type == CASS_VALUE_TYPE_BLOB) {
                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t *size = (uint64_t *) from_data;

                void *new_data = malloc(*size);
                memcpy(new_data, from_data, *size + sizeof(uint64_t));
                //Copy ptr
                memcpy(values + values_meta->at(i).position, &new_data, values_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_TEXT || type == CASS_VALUE_TYPE_VARCHAR ||
                       type == CASS_VALUE_TYPE_ASCII) {

                char **from = (char **) element_i;
                char *from_data = *from;

                uint64_t size = strlen(from_data);

                void *new_data = malloc(size);
                memcpy(new_data, from_data, size);
                //Copy ptr
                memcpy(values + values_meta->at(i).position, &new_data, values_meta->at(i).size);
            } else if (type == CASS_VALUE_TYPE_UUID) {

                uint64_t **from = (uint64_t **) element_i;

                uint64_t size = sizeof(uint64_t) * 2;
                void *new_data = malloc(size);
                memcpy(new_data, *from, size);
                //Copy ptr
                memcpy(values + values_meta->at(i).position, &new_data, values_meta->at(i).size);
            } else memcpy(values + values_meta->at(i).position, element_i, values_meta->at(i).size);
        } else v->setNull(i);
    }
    this->add_to_cache(keys, values);
}

/*
 * POST: never returns NULL
 */
std::vector<const TupleRow *> CacheTable::retrieve_from_cassandra(const TupleRow *keys) {

    /* Not present on cache, a query is performed */
    CassStatement *statement = cass_prepared_bind(prepared_query);

    this->keys_factory->bind(statement, keys, 0);

    CassFuture *query_future = cass_session_execute(session, statement);
    const CassResult *result = cass_future_get_result(query_future);
    CassError rc = cass_future_error_code(query_future);
    if (result == NULL) {
        /* Handle error */
        std::string error(cass_error_desc(rc));
        cass_future_free(query_future);
        cass_statement_free(statement);
        throw ModuleException("CacheTable: Get row error on result" + error);
    }

    cass_future_free(query_future);
    cass_statement_free(statement);

    uint32_t counter = 0;
    std::vector<const TupleRow *> values(cass_result_row_count(result));

    const CassRow *row;
    CassIterator *it = cass_iterator_from_result(result);
    while (cass_iterator_next(it)) {
        row = cass_iterator_get_row(it);
        values[counter] = values_factory->make_tuple(row);
        ++counter;
    }
    cass_iterator_free(it);
    cass_result_free(result);
    return values;
}

std::vector<const TupleRow *> CacheTable::get_crow(const TupleRow *keys) {
    if (myCache) {
        Poco::SharedPtr<TupleRow> ptrElem = myCache->get(*keys);
        if (!ptrElem.isNull()) return std::vector<const TupleRow *> {new TupleRow(ptrElem.get())};
    }

    std::vector<const TupleRow *> values = retrieve_from_cassandra(keys);

    if (myCache && !values.empty()) myCache->add(*keys, values[0]);

    return values;
}

std::vector<const TupleRow *> CacheTable::get_crow(void *keys) {
    const TupleRow *tuple_key = keys_factory->make_tuple(keys);
    std::vector<const TupleRow *> result = get_crow(tuple_key);
    delete (tuple_key);
    return result;
}

void CacheTable::delete_crow(const TupleRow *keys) {

    //Remove row from Cassandra
    CassStatement *statement = cass_prepared_bind(delete_query);

    this->keys_factory->bind(statement, keys, 0);

    CassFuture *query_future = cass_session_execute(session, statement);
    const CassResult *result = cass_future_get_result(query_future);
    CassError rc = cass_future_error_code(query_future);
    if (result == NULL) {
        /* Handle error */
        std::string error(cass_error_desc(rc));
        cass_future_free(query_future);
        cass_statement_free(statement);
        throw ModuleException("CacheTable: Delete row error on result" + error);
    }

    cass_future_free(query_future);
    cass_statement_free(statement);
    cass_result_free(result);

    //Remove entry from cache
    if (myCache) myCache->Remove(*keys);
}<|endoftext|>


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

#if !DEVICE_LPTICKER
#error [NOT_SUPPORTED] Low power timer not supported for this target
#endif

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "utest/utest.h"
#include "unity/unity.h"
#include "../timeout/timeout_tests.h"

using namespace utest::v1;

utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
    greentea_case_failure_abort_handler(source, reason);
    return STATUS_CONTINUE;
}

Case cases[] = {
    Case("Callback called once (attach)", test_single_call<AttachTester<LowPowerTimeout> >),
    Case("Callback called once (attach_us)", test_single_call<AttachUSTester<LowPowerTimeout> >),

    Case("Callback not called when cancelled (attach)", test_cancel<AttachTester<LowPowerTimeout> >),
    Case("Callback not called when cancelled (attach_us)", test_cancel<AttachUSTester<LowPowerTimeout> >),

    Case("Callback override (attach)", test_override<AttachTester<LowPowerTimeout> >),
    Case("Callback override (attach_us)", test_override<AttachUSTester<LowPowerTimeout> >),

    Case("Multiple timeouts running in parallel (attach)", test_multiple<AttachTester<LowPowerTimeout> >),
    Case("Multiple timeouts running in parallel (attach_us)", test_multiple<AttachUSTester<LowPowerTimeout> >),

    Case("Zero delay (attach)", test_no_wait<AttachTester<LowPowerTimeout> >),
    Case("Zero delay (attach_us)", test_no_wait<AttachUSTester<LowPowerTimeout> >),

    Case("10 ms delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
         greentea_failure_handler),
    Case("10 ms delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
         greentea_failure_handler),

    Case("1 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("1 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),

    Case("5 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("5 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
         greentea_failure_handler),

#if DEVICE_SLEEP
    Case("1 s delay during sleep (attach)", test_sleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("1 s delay during sleep (attach_us)", test_sleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),

    Case("1 s delay during deepsleep (attach)", test_deepsleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("1 s delay during deepsleep (attach_us)", test_deepsleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
#endif

    Case("Timing drift (attach)", test_drift<AttachTester<LowPowerTimeout> >),
    Case("Timing drift (attach_us)", test_drift<AttachUSTester<LowPowerTimeout> >),
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
    GREENTEA_SETUP(240, "timing_drift_auto");
    return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main()
{
    Harness::run(specification);
}
<commit_msg>FastModel: Skip low-power ticker time drifting test for models<commit_after>/* mbed Microcontroller Library
 * Copyright (c) 2016 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#if !DEVICE_LPTICKER
#error [NOT_SUPPORTED] Low power timer not supported for this target
#endif

#include "mbed.h"
#include "greentea-client/test_env.h"
#include "utest/utest.h"
#include "unity/unity.h"
#include "../timeout/timeout_tests.h"

using namespace utest::v1;

utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
    greentea_case_failure_abort_handler(source, reason);
    return STATUS_CONTINUE;
}

Case cases[] = {
    Case("Callback called once (attach)", test_single_call<AttachTester<LowPowerTimeout> >),
    Case("Callback called once (attach_us)", test_single_call<AttachUSTester<LowPowerTimeout> >),

    Case("Callback not called when cancelled (attach)", test_cancel<AttachTester<LowPowerTimeout> >),
    Case("Callback not called when cancelled (attach_us)", test_cancel<AttachUSTester<LowPowerTimeout> >),

    Case("Callback override (attach)", test_override<AttachTester<LowPowerTimeout> >),
    Case("Callback override (attach_us)", test_override<AttachUSTester<LowPowerTimeout> >),

    Case("Multiple timeouts running in parallel (attach)", test_multiple<AttachTester<LowPowerTimeout> >),
    Case("Multiple timeouts running in parallel (attach_us)", test_multiple<AttachUSTester<LowPowerTimeout> >),

    Case("Zero delay (attach)", test_no_wait<AttachTester<LowPowerTimeout> >),
    Case("Zero delay (attach_us)", test_no_wait<AttachUSTester<LowPowerTimeout> >),

    Case("10 ms delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
         greentea_failure_handler),
    Case("10 ms delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 10000, SHORT_DELTA_US>,
         greentea_failure_handler),

    Case("1 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("1 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),

    Case("5 s delay accuracy (attach)", test_delay_accuracy<AttachTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("5 s delay accuracy (attach_us)", test_delay_accuracy<AttachUSTester<LowPowerTimeout>, 5000000, LONG_DELTA_US>,
         greentea_failure_handler),

#if DEVICE_SLEEP
    Case("1 s delay during sleep (attach)", test_sleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("1 s delay during sleep (attach_us)", test_sleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),

    Case("1 s delay during deepsleep (attach)", test_deepsleep<AttachTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
    Case("1 s delay during deepsleep (attach_us)", test_deepsleep<AttachUSTester<LowPowerTimeout>, 1000000, LONG_DELTA_US>,
         greentea_failure_handler),
#endif
#if !defined(__ARM_FM)  //FastModels not support time drifting test
    Case("Timing drift (attach)", test_drift<AttachTester<LowPowerTimeout> >),
    Case("Timing drift (attach_us)", test_drift<AttachUSTester<LowPowerTimeout> >),
#endif
};

utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
{
    GREENTEA_SETUP(240, "timing_drift_auto");
    return greentea_test_setup_handler(number_of_cases);
}

Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);

int main()
{
    Harness::run(specification);
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkObjectParser.h"
#include "SkData.h"
#include "SkFontDescriptor.h"
#include "SkRRect.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkStringUtils.h"
#include "SkTypeface.h"

/* TODO(chudy): Replace all std::strings with char */

SkString* SkObjectParser::BitmapToString(const SkBitmap& bitmap) {
    SkString* mBitmap = new SkString("SkBitmap: ");
    mBitmap->append("W: ");
    mBitmap->appendS32(bitmap.width());
    mBitmap->append(" H: ");
    mBitmap->appendS32(bitmap.height());

    const char* gConfigStrings[] = {
        "None", "A1", "A8", "Index8", "RGB565", "ARGB4444", "ARGB8888", "RLE8"
    };
    SkASSERT(SkBitmap::kConfigCount == 8);

    mBitmap->append(" Config: ");
    mBitmap->append(gConfigStrings[bitmap.getConfig()]);

    if (bitmap.isOpaque()) {
        mBitmap->append(" opaque");
    } else {
        mBitmap->append(" not-opaque");
    }

    if (bitmap.isImmutable()) {
        mBitmap->append(" immutable");
    } else {
        mBitmap->append(" not-immutable");
    }

    if (bitmap.isVolatile()) {
        mBitmap->append(" volatile");
    } else {
        mBitmap->append(" not-volatile");
    }

    mBitmap->append(" genID: ");
    mBitmap->appendS32(bitmap.getGenerationID());

    return mBitmap;
}

SkString* SkObjectParser::BoolToString(bool doAA) {
    SkString* mBool = new SkString("Bool doAA: ");
    if (doAA) {
        mBool->append("True");
    } else {
        mBool->append("False");
    }
    return mBool;
}

SkString* SkObjectParser::CustomTextToString(const char* text) {
    SkString* mText = new SkString(text);
    return mText;
}

SkString* SkObjectParser::IntToString(int x, const char* text) {
    SkString* mInt = new SkString(text);
    mInt->append(" ");
    mInt->appendScalar(SkIntToScalar(x));
    return mInt;
}

SkString* SkObjectParser::IRectToString(const SkIRect& rect) {
    SkString* mRect = new SkString("SkIRect: ");
    mRect->append("L: ");
    mRect->appendS32(rect.left());
    mRect->append(", T: ");
    mRect->appendS32(rect.top());
    mRect->append(", R: ");
    mRect->appendS32(rect.right());
    mRect->append(", B: ");
    mRect->appendS32(rect.bottom());
    return mRect;
}

SkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) {
    SkString* str = new SkString("SkMatrix: ");
    matrix.toString(str);
    return str;
}

SkString* SkObjectParser::PaintToString(const SkPaint& paint) {
    SkString* str = new SkString;
    paint.toString(str);
    return str;
}

SkString* SkObjectParser::PathToString(const SkPath& path) {
    SkString* mPath = new SkString("Path (");

    static const char* gFillStrings[] = {
        "Winding", "EvenOdd", "InverseWinding", "InverseEvenOdd"
    };

    mPath->append(gFillStrings[path.getFillType()]);
    mPath->append(", ");

    static const char* gConvexityStrings[] = {
        "Unknown", "Convex", "Concave"
    };
    SkASSERT(SkPath::kConcave_Convexity == 2);

    mPath->append(gConvexityStrings[path.getConvexity()]);
    mPath->append(", ");

    if (path.isRect(NULL)) {
        mPath->append("isRect, ");
    } else {
        mPath->append("isNotRect, ");
    }

    mPath->appendS32(path.countVerbs());
    mPath->append("V, ");
    mPath->appendS32(path.countPoints());
    mPath->append("P): ");

    static const char* gVerbStrings[] = {
        "Move", "Line", "Quad", "Cubic", "Close", "Done"
    };
    static const int gPtsPerVerb[] = { 1, 1, 2, 3, 0, 0 };
    static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 0, 0 };
    SkASSERT(SkPath::kDone_Verb == 5);

    SkPath::Iter iter(const_cast<SkPath&>(path), false);
    SkPath::Verb verb;
    SkPoint points[4];

    for(verb = iter.next(points, false);
        verb != SkPath::kDone_Verb;
        verb = iter.next(points, false)) {

        mPath->append(gVerbStrings[verb]);
        mPath->append(" ");

        for (int i = 0; i < gPtsPerVerb[verb]; ++i) {
            mPath->append("(");
            mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fX);
            mPath->append(", ");
            mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fY);
            mPath->append(") ");
        }
    }

    SkString* boundStr = SkObjectParser::RectToString(path.getBounds(), "    Bound: ");

    if (NULL != boundStr) {
        mPath->append(*boundStr);
        SkDELETE(boundStr);
    }

    return mPath;
}

SkString* SkObjectParser::PointsToString(const SkPoint pts[], size_t count) {
    SkString* mPoints = new SkString("SkPoints pts[]: ");
    for (unsigned int i = 0; i < count; i++) {
        mPoints->append("(");
        mPoints->appendScalar(pts[i].fX);
        mPoints->append(",");
        mPoints->appendScalar(pts[i].fY);
        mPoints->append(")");
    }
    return mPoints;
}

SkString* SkObjectParser::PointModeToString(SkCanvas::PointMode mode) {
    SkString* mMode = new SkString("SkCanvas::PointMode: ");
    if (mode == SkCanvas::kPoints_PointMode) {
        mMode->append("kPoints_PointMode");
    } else if (mode == SkCanvas::kLines_PointMode) {
        mMode->append("kLines_Mode");
    } else if (mode == SkCanvas::kPolygon_PointMode) {
        mMode->append("kPolygon_PointMode");
    }
    return mMode;
}

SkString* SkObjectParser::RectToString(const SkRect& rect, const char* title) {

    SkString* mRect = new SkString;

    if (NULL == title) {
        mRect->append("SkRect: ");
    } else {
        mRect->append(title);
    }
    mRect->append("(");
    mRect->appendScalar(rect.left());
    mRect->append(", ");
    mRect->appendScalar(rect.top());
    mRect->append(", ");
    mRect->appendScalar(rect.right());
    mRect->append(", ");
    mRect->appendScalar(rect.bottom());
    mRect->append(")");
    return mRect;
}

SkString* SkObjectParser::RRectToString(const SkRRect& rrect, const char* title) {

    SkString* mRRect = new SkString;

    if (NULL == title) {
        mRRect->append("SkRRect (");
        if (rrect.isEmpty()) {
            mRRect->append("empty");
        } else if (rrect.isRect()) {
            mRRect->append("rect");
        } else if (rrect.isOval()) {
            mRRect->append("oval");
        } else if (rrect.isSimple()) {
            mRRect->append("simple");
        } else {
            SkASSERT(rrect.isComplex());
            mRRect->append("complex");
        }
        mRRect->append("): ");
    } else {
        mRRect->append(title);
    }
    mRRect->append("(");
    mRRect->appendScalar(rrect.rect().left());
    mRRect->append(", ");
    mRRect->appendScalar(rrect.rect().top());
    mRRect->append(", ");
    mRRect->appendScalar(rrect.rect().right());
    mRRect->append(", ");
    mRRect->appendScalar(rrect.rect().bottom());
    mRRect->append(") radii: (");
    for (int i = 0; i < 4; ++i) {
        const SkVector& radii = rrect.radii((SkRRect::Corner) i);
        mRRect->appendScalar(radii.fX);
        mRRect->append(", ");
        mRRect->appendScalar(radii.fY);
        if (i < 3) {
            mRRect->append(", ");
        }
    }
    mRRect->append(")");
    return mRRect;
}

SkString* SkObjectParser::RegionOpToString(SkRegion::Op op) {
    SkString* mOp = new SkString("SkRegion::Op: ");
    if (op == SkRegion::kDifference_Op) {
        mOp->append("kDifference_Op");
    } else if (op == SkRegion::kIntersect_Op) {
        mOp->append("kIntersect_Op");
    } else if (op == SkRegion::kUnion_Op) {
        mOp->append("kUnion_Op");
    } else if (op == SkRegion::kXOR_Op) {
        mOp->append("kXOR_Op");
    } else if (op == SkRegion::kReverseDifference_Op) {
        mOp->append("kReverseDifference_Op");
    } else if (op == SkRegion::kReplace_Op) {
        mOp->append("kReplace_Op");
    } else {
        mOp->append("Unknown Type");
    }
    return mOp;
}

SkString* SkObjectParser::RegionToString(const SkRegion& region) {
    SkString* mRegion = new SkString("SkRegion: Data unavailable.");
    return mRegion;
}

SkString* SkObjectParser::SaveFlagsToString(SkCanvas::SaveFlags flags) {
    SkString* mFlags = new SkString("SkCanvas::SaveFlags: ");
    if(flags == SkCanvas::kMatrixClip_SaveFlag) {
        mFlags->append("kMatrixClip_SaveFlag");
    } else if (flags == SkCanvas::kClip_SaveFlag) {
        mFlags->append("kClip_SaveFlag");
    } else if (flags == SkCanvas::kHasAlphaLayer_SaveFlag) {
        mFlags->append("kHasAlphaLayer_SaveFlag");
    } else if (flags == SkCanvas::kFullColorLayer_SaveFlag) {
        mFlags->append("kFullColorLayer_SaveFlag");
    } else if (flags == SkCanvas::kClipToLayer_SaveFlag) {
        mFlags->append("kClipToLayer_SaveFlag");
    } else if (flags == SkCanvas::kMatrixClip_SaveFlag) {
        mFlags->append("kMatrixClip_SaveFlag");
    } else if (flags == SkCanvas::kARGB_NoClipLayer_SaveFlag) {
        mFlags->append("kARGB_NoClipLayer_SaveFlag");
    } else if (flags == SkCanvas::kARGB_ClipLayer_SaveFlag) {
        mFlags->append("kARGB_ClipLayer_SaveFlag");
    } else {
        mFlags->append("Data Unavailable");
    }
    return mFlags;
}

SkString* SkObjectParser::ScalarToString(SkScalar x, const char* text) {
    SkString* mScalar = new SkString(text);
    mScalar->append(" ");
    mScalar->appendScalar(x);
    return mScalar;
}

SkString* SkObjectParser::TextToString(const void* text, size_t byteLength) {
    SkString* mText = new SkString(6+byteLength+1);
    mText->append("Text: ");
    mText->append((char*) text, byteLength);
    return mText;
}
<commit_msg>Added SK_DEVELOPER wrapper's around toString calls in debugger's SkObjectParser<commit_after>
/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkObjectParser.h"
#include "SkData.h"
#include "SkFontDescriptor.h"
#include "SkRRect.h"
#include "SkShader.h"
#include "SkStream.h"
#include "SkStringUtils.h"
#include "SkTypeface.h"

/* TODO(chudy): Replace all std::strings with char */

SkString* SkObjectParser::BitmapToString(const SkBitmap& bitmap) {
    SkString* mBitmap = new SkString("SkBitmap: ");
    mBitmap->append("W: ");
    mBitmap->appendS32(bitmap.width());
    mBitmap->append(" H: ");
    mBitmap->appendS32(bitmap.height());

    const char* gConfigStrings[] = {
        "None", "A1", "A8", "Index8", "RGB565", "ARGB4444", "ARGB8888", "RLE8"
    };
    SkASSERT(SkBitmap::kConfigCount == 8);

    mBitmap->append(" Config: ");
    mBitmap->append(gConfigStrings[bitmap.getConfig()]);

    if (bitmap.isOpaque()) {
        mBitmap->append(" opaque");
    } else {
        mBitmap->append(" not-opaque");
    }

    if (bitmap.isImmutable()) {
        mBitmap->append(" immutable");
    } else {
        mBitmap->append(" not-immutable");
    }

    if (bitmap.isVolatile()) {
        mBitmap->append(" volatile");
    } else {
        mBitmap->append(" not-volatile");
    }

    mBitmap->append(" genID: ");
    mBitmap->appendS32(bitmap.getGenerationID());

    return mBitmap;
}

SkString* SkObjectParser::BoolToString(bool doAA) {
    SkString* mBool = new SkString("Bool doAA: ");
    if (doAA) {
        mBool->append("True");
    } else {
        mBool->append("False");
    }
    return mBool;
}

SkString* SkObjectParser::CustomTextToString(const char* text) {
    SkString* mText = new SkString(text);
    return mText;
}

SkString* SkObjectParser::IntToString(int x, const char* text) {
    SkString* mInt = new SkString(text);
    mInt->append(" ");
    mInt->appendScalar(SkIntToScalar(x));
    return mInt;
}

SkString* SkObjectParser::IRectToString(const SkIRect& rect) {
    SkString* mRect = new SkString("SkIRect: ");
    mRect->append("L: ");
    mRect->appendS32(rect.left());
    mRect->append(", T: ");
    mRect->appendS32(rect.top());
    mRect->append(", R: ");
    mRect->appendS32(rect.right());
    mRect->append(", B: ");
    mRect->appendS32(rect.bottom());
    return mRect;
}

SkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) {
    SkString* str = new SkString("SkMatrix: ");
#ifdef SK_DEVELOPER
    matrix.toString(str);
#endif
    return str;
}

SkString* SkObjectParser::PaintToString(const SkPaint& paint) {
    SkString* str = new SkString;
#ifdef SK_DEVELOPER
    paint.toString(str);
#endif
    return str;
}

SkString* SkObjectParser::PathToString(const SkPath& path) {
    SkString* mPath = new SkString("Path (");

    static const char* gFillStrings[] = {
        "Winding", "EvenOdd", "InverseWinding", "InverseEvenOdd"
    };

    mPath->append(gFillStrings[path.getFillType()]);
    mPath->append(", ");

    static const char* gConvexityStrings[] = {
        "Unknown", "Convex", "Concave"
    };
    SkASSERT(SkPath::kConcave_Convexity == 2);

    mPath->append(gConvexityStrings[path.getConvexity()]);
    mPath->append(", ");

    if (path.isRect(NULL)) {
        mPath->append("isRect, ");
    } else {
        mPath->append("isNotRect, ");
    }

    mPath->appendS32(path.countVerbs());
    mPath->append("V, ");
    mPath->appendS32(path.countPoints());
    mPath->append("P): ");

    static const char* gVerbStrings[] = {
        "Move", "Line", "Quad", "Cubic", "Close", "Done"
    };
    static const int gPtsPerVerb[] = { 1, 1, 2, 3, 0, 0 };
    static const int gPtOffsetPerVerb[] = { 0, 1, 1, 1, 0, 0 };
    SkASSERT(SkPath::kDone_Verb == 5);

    SkPath::Iter iter(const_cast<SkPath&>(path), false);
    SkPath::Verb verb;
    SkPoint points[4];

    for(verb = iter.next(points, false);
        verb != SkPath::kDone_Verb;
        verb = iter.next(points, false)) {

        mPath->append(gVerbStrings[verb]);
        mPath->append(" ");

        for (int i = 0; i < gPtsPerVerb[verb]; ++i) {
            mPath->append("(");
            mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fX);
            mPath->append(", ");
            mPath->appendScalar(points[gPtOffsetPerVerb[verb]+i].fY);
            mPath->append(") ");
        }
    }

    SkString* boundStr = SkObjectParser::RectToString(path.getBounds(), "    Bound: ");

    if (NULL != boundStr) {
        mPath->append(*boundStr);
        SkDELETE(boundStr);
    }

    return mPath;
}

SkString* SkObjectParser::PointsToString(const SkPoint pts[], size_t count) {
    SkString* mPoints = new SkString("SkPoints pts[]: ");
    for (unsigned int i = 0; i < count; i++) {
        mPoints->append("(");
        mPoints->appendScalar(pts[i].fX);
        mPoints->append(",");
        mPoints->appendScalar(pts[i].fY);
        mPoints->append(")");
    }
    return mPoints;
}

SkString* SkObjectParser::PointModeToString(SkCanvas::PointMode mode) {
    SkString* mMode = new SkString("SkCanvas::PointMode: ");
    if (mode == SkCanvas::kPoints_PointMode) {
        mMode->append("kPoints_PointMode");
    } else if (mode == SkCanvas::kLines_PointMode) {
        mMode->append("kLines_Mode");
    } else if (mode == SkCanvas::kPolygon_PointMode) {
        mMode->append("kPolygon_PointMode");
    }
    return mMode;
}

SkString* SkObjectParser::RectToString(const SkRect& rect, const char* title) {

    SkString* mRect = new SkString;

    if (NULL == title) {
        mRect->append("SkRect: ");
    } else {
        mRect->append(title);
    }
    mRect->append("(");
    mRect->appendScalar(rect.left());
    mRect->append(", ");
    mRect->appendScalar(rect.top());
    mRect->append(", ");
    mRect->appendScalar(rect.right());
    mRect->append(", ");
    mRect->appendScalar(rect.bottom());
    mRect->append(")");
    return mRect;
}

SkString* SkObjectParser::RRectToString(const SkRRect& rrect, const char* title) {

    SkString* mRRect = new SkString;

    if (NULL == title) {
        mRRect->append("SkRRect (");
        if (rrect.isEmpty()) {
            mRRect->append("empty");
        } else if (rrect.isRect()) {
            mRRect->append("rect");
        } else if (rrect.isOval()) {
            mRRect->append("oval");
        } else if (rrect.isSimple()) {
            mRRect->append("simple");
        } else {
            SkASSERT(rrect.isComplex());
            mRRect->append("complex");
        }
        mRRect->append("): ");
    } else {
        mRRect->append(title);
    }
    mRRect->append("(");
    mRRect->appendScalar(rrect.rect().left());
    mRRect->append(", ");
    mRRect->appendScalar(rrect.rect().top());
    mRRect->append(", ");
    mRRect->appendScalar(rrect.rect().right());
    mRRect->append(", ");
    mRRect->appendScalar(rrect.rect().bottom());
    mRRect->append(") radii: (");
    for (int i = 0; i < 4; ++i) {
        const SkVector& radii = rrect.radii((SkRRect::Corner) i);
        mRRect->appendScalar(radii.fX);
        mRRect->append(", ");
        mRRect->appendScalar(radii.fY);
        if (i < 3) {
            mRRect->append(", ");
        }
    }
    mRRect->append(")");
    return mRRect;
}

SkString* SkObjectParser::RegionOpToString(SkRegion::Op op) {
    SkString* mOp = new SkString("SkRegion::Op: ");
    if (op == SkRegion::kDifference_Op) {
        mOp->append("kDifference_Op");
    } else if (op == SkRegion::kIntersect_Op) {
        mOp->append("kIntersect_Op");
    } else if (op == SkRegion::kUnion_Op) {
        mOp->append("kUnion_Op");
    } else if (op == SkRegion::kXOR_Op) {
        mOp->append("kXOR_Op");
    } else if (op == SkRegion::kReverseDifference_Op) {
        mOp->append("kReverseDifference_Op");
    } else if (op == SkRegion::kReplace_Op) {
        mOp->append("kReplace_Op");
    } else {
        mOp->append("Unknown Type");
    }
    return mOp;
}

SkString* SkObjectParser::RegionToString(const SkRegion& region) {
    SkString* mRegion = new SkString("SkRegion: Data unavailable.");
    return mRegion;
}

SkString* SkObjectParser::SaveFlagsToString(SkCanvas::SaveFlags flags) {
    SkString* mFlags = new SkString("SkCanvas::SaveFlags: ");
    if(flags == SkCanvas::kMatrixClip_SaveFlag) {
        mFlags->append("kMatrixClip_SaveFlag");
    } else if (flags == SkCanvas::kClip_SaveFlag) {
        mFlags->append("kClip_SaveFlag");
    } else if (flags == SkCanvas::kHasAlphaLayer_SaveFlag) {
        mFlags->append("kHasAlphaLayer_SaveFlag");
    } else if (flags == SkCanvas::kFullColorLayer_SaveFlag) {
        mFlags->append("kFullColorLayer_SaveFlag");
    } else if (flags == SkCanvas::kClipToLayer_SaveFlag) {
        mFlags->append("kClipToLayer_SaveFlag");
    } else if (flags == SkCanvas::kMatrixClip_SaveFlag) {
        mFlags->append("kMatrixClip_SaveFlag");
    } else if (flags == SkCanvas::kARGB_NoClipLayer_SaveFlag) {
        mFlags->append("kARGB_NoClipLayer_SaveFlag");
    } else if (flags == SkCanvas::kARGB_ClipLayer_SaveFlag) {
        mFlags->append("kARGB_ClipLayer_SaveFlag");
    } else {
        mFlags->append("Data Unavailable");
    }
    return mFlags;
}

SkString* SkObjectParser::ScalarToString(SkScalar x, const char* text) {
    SkString* mScalar = new SkString(text);
    mScalar->append(" ");
    mScalar->appendScalar(x);
    return mScalar;
}

SkString* SkObjectParser::TextToString(const void* text, size_t byteLength) {
    SkString* mText = new SkString(6+byteLength+1);
    mText->append("Text: ");
    mText->append((char*) text, byteLength);
    return mText;
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Andrew Sutton
// All rights reserved

#ifndef LINGO_ALGORITHM_HPP
#define LINGO_ALGORITHM_HPP

// The algorithm module defines a set of matching algorithms suitable
// for use in lexers and parsers. These typically operate on character
// and token streams, and support matching against a variety of
// different patterns.
//
// Note that more specialized algorithms can be found in the lexing
// and parsing modules.

#include <algorithm>
#include <type_traits>
#include <iostream>

namespace lingo
{

// The iterator type of an aggregate.
template<typename T>
using Iterator_type = decltype(std::begin(std::declval<T>()));

// The value type of a stream.
template<typename T>
using Value_type = typename T::value_type;

// The argument type of a transform (lexer or parser).
template<typename T>
using Argument_type = typename T::argument_type;

// The result type of a transform (lexer or parser).
template<typename T>
using Result_type = typename T::result_type;

// Yields the return type of the given call expression.
template<typename Call>
using Result_of = typename std::result_of<Call>::type;

// A Range is a pair of iterators.
template<typename I>
struct Range
{
  Range()
    : first(), last(first)
  { }

  Range(I f, I l)
    : first(f), last(l)
  { }

  bool empty() const { return first == last; }
  I begin() const { return first; }
  I end() const   { return last; }

  // Converts to true iff not empty.
  explicit operator bool() const { return !empty(); }

  I first;
  I last;
};

// An alias used to constraint ranges over containers or streams.
template<typename T>
using Range_over = Range<Iterator_type<T>>;

// -------------------------------------------------------------------------- //
//                              Next element

// Returns true if the next element in the stream is equal to x.
template<typename Stream, typename T>
inline bool
next_element_is(Stream const& s, T const& x)
{
  return !s.eof() && s.peek() == x;
}

// Returns true if the next element in the stream is distinct
// from x.
template<typename Stream, typename T>
inline bool
next_element_is_not(Stream const& s, T const& x)
{
  return !s.eof() && s.peek() != x;
}

// Returns true if the nth element in the stream is equal to x.
template<typename Stream, typename T>
inline bool
nth_element_is(Stream const& s, int n, T const& x)
{
  return !s.eof() && s.peek(n) == x;
}

// Returns true if the next element satisfies the given predicate.
template<typename Stream, typename Pred>
inline bool
next_element_if_unguarded(Stream const& s, Pred pred)
{
  return pred(s.peek());
}

// Returns true if the next element satisfies the given predicate.
template<typename Stream, typename Pred>
inline bool
next_element_if(Stream const& s, Pred pred)
{
  return !s.eof() && pred(s.peek());
}

// -------------------------------------------------------------------------- //
//                         Next element in

// Returns false when there are no elements to match.
template<typename Stream>
inline bool
next_element_in(Stream const& s)
{
  return false;
}

// Returns true when the element matches in the set of elements
// given by [first, args...].
template<typename Stream, typename T, typename... Args>
inline bool
next_element_in(Stream const& s, T const& first, Args const&... args)
{
  if (next_element_is(s, first))
    return true;
  else
    return next_element_in(s, args...);
}

// -------------------------------------------------------------------------- //
//                         Next elements are

// Base case. Returns false.
template<typename Stream>
inline bool
next_elements_past_n_are(Stream const& s, int)
{
  return true;
}

// Rerusive step. Match the nth element and check the rest.
template<typename Stream, typename T, typename... Args>
inline bool
next_elements_past_n_are(Stream const& s, int n, T const& first, Args const&... args)
{
  if (nth_element_is(s, n, first))
    return next_elements_past_n_are(s, n + 1, args...);
  return false;
}

// Returns true when the next elements in match those given
// in by args.... Note that this operation requires lookahead
// of sizeof...(Args).
//
// If the required lookahead exceeds the buffer, this returns
// false.
template<typename Stream, typename T, typename... Args>
inline bool
next_elements_are(Stream const& s, Args const&... args)
{
  return next_elements_past_n_are(s, 0, args...);
}

// -------------------------------------------------------------------------- //
//                               Match
//
// The matching algorithms operate on streams. A stream `s` is required
// to support the following operations:
//
// - `s.eof()` -- returns true when the stream is at the end of file.
// - `s.peek()` -- returns a reference to the current element
// - `s.get()` -- returns a reference to the current element and advances
//
// Additionally, the iterator type must be the same `&s.get()`,
// and default constructing the iterator type must be contextually
// convertible to bool. This is typically a pointer into the stream.

// If the current element of the stream exactly matches t, then
// return an iterator to that element and advance the stream.
// Otherwise, return a null iterator.
//
// If the stream is past the end, then it does not match.
template<typename Stream, typename T>
inline Iterator_type<Stream>
match(Stream& s, T const& t)
{
  if (!s.eof() && s.peek() == t)
    return &s.get();
  else
    return {};
}

// If the current element stream satisfis the predicate `pred`,
// then return an iterator to that element. Otherwise, return the
// null iterator.
template<typename Stream, typename P>
inline Iterator_type<Stream>
match_if(Stream& s, P pred)
{
  if (!s.eof() && pred(s.peek()))
    return &s.get();
  else
    return {};
}

// -------------------------------------------------------------------------- //
//                            Match any

// The base case for match_any returns the null element.
template<typename Stream>
inline Iterator_type<Stream>
match_any(Stream& s)
{
  return {};
}

// If the current element in the stream matches any element
// in the argument pack [a, args...], return that element.
// Otherwise, return the null element.
template<typename Stream, typename A, typename... Args>
inline Iterator_type<Stream>
match_any(Stream& s, A const& a, Args const&... args)
{
  if (auto iter = match(s, a))
    return iter;
  else
    return match_any(s, args...);
}

// -------------------------------------------------------------------------- //
//                            Match any if

// The base case for match_any_if returns the null element.
template<typename Stream>
inline Iterator_type<Stream>
match_any_if(Stream& s)
{
  return {};
}

// If the current element in the stream satisfies one of
// the predicates in [pred, preds...], return the position of
// that element and advance the stream. Otherwise, return
// the null element.
template<typename Stream, typename P, typename... Preds>
inline Iterator_type<Stream>
match_any_if(Stream& s, P pred, Preds const&... preds)
{
  if (auto iter = match_if(s, pred))
    return iter;
  else
    return match_any_if(s, preds...);
}

// -------------------------------------------------------------------------- //
//                            Match all

// The base case for match_all returns current element.
template<typename Stream>
inline Iterator_type<Stream>
match_all(Stream& s)
{
  return s.begin();
}

// If the current element in the stream matches each element
// in the argument pack [a, args...], return a pointer past
// the last matched element. Otherwise, returns the null
// element.
template<typename Stream, typename A, typename... Args>
inline Iterator_type<Stream>
match_all(Stream& s, A const& a, Args const&... args)
{
  if (match(s, a))
    return match_all(s, args...);
  else
    return {};
}

// -------------------------------------------------------------------------- //
//                            Match range

// Returns an iterator range corresponding to a sequence
// of matched elements in the stream when the current element
// of the stream satisfies `pred`.
template<typename Stream, typename P>
inline Range_over<Stream>
match_range_after_first(Stream& s, P pred)
{
  assert(pred(s));
  Iterator_type<Stream> first = &s.get(); // Save the first position
  while (!s.eof() && pred(s)) {
    s.get();
  }
  Iterator_type<Stream> last = s.begin(); // Past the end of the range
  return {first, last};
}

// Returns an iterator range corresponding to a sequence
// of matched elements in the stream. If the current element
// is not in the set designated by match, the resulting range
// is empty.
template<typename Stream, typename P>
inline Range_over<Stream>
match_range(Stream& s, P pred)
{
  if (s.eof())
    return {s.end(), s.end()};
  if (!match(s))
    return {s.begin(), s.begin()};
  return match_range_after_first(s, match);
}

// -------------------------------------------------------------------------- //
//                            Get n elements

// Get n elements in the stream that satisfy the given
// predicate until reachin the first that does not. Returns
// an iterator to the first element discarded.
template<typename Stream>
inline Iterator_type<Stream>
get_n(Stream& s, int n)
{
  auto iter = s.begin();
  while (!s.eof() && n != 0)
    --n;
  return iter;
}

// -------------------------------------------------------------------------- //
//                              Discard if

// Discard all elements in the stream that satisfy the given
// predicate until reachin the first that does not. Returns
// an iterator to the first element discarded.
template<typename Stream, typename P>
inline Iterator_type<Stream>
discard_if(Stream& s, P pred)
{
  auto iter = s.begin();
  while (!s.eof() && pred(s))
    s.get();
  return iter;
}

// -------------------------------------------------------------------------- //
//                            Expect element
//
// The expect* algorithms are similar to the match algorithms except
// that diagnostics are emitted when the match fails. To support
// diagnostics, these algorithms also require the stream to provide
// support for source code locations. For any stream `s`
//
//    s.location()
//
// returns the current location in the underlying file or buffer. The
// only requirement for this type is that it is semiregular.
//
// To support generic diagnostics, the expect* algorithms require a
// context parameter, which defines the context of translation. The
// context must define the following functions:
//
//    cxt.on_expected(loc, t)
//    cxt.on_expected(loc, str)
//
// Where `loc` is a value returned by `s.location()`, `t` is an element
// in the stream and `str` is a C-string.

// If the current element matches of the stream the given kind,
// advance the stream, returning an iterator to the matched
// element. Otherwise, calls the on_expected error in the
// context.
template<typename Context, typename Stream, typename T>
Iterator_type<Stream>
expect(Context& cxt, Stream& s, T const& t)
{
  if (auto iter = match(s, t)) {
    return iter;
  } else {
    cxt.on_expected(s.location(), t);
    return {};
  }
}

// If the current element matches satisfies the predicate `pred`,
// return an iterator to that element and advance the stream.
// The `cond` string is used to provide feedback to the translation
// via the `on_expected` methods.
template<typename Context, typename Stream, typename P>
Iterator_type<Stream>
expect_if(Context& cxt, Stream& s, P pred, char const* cond)
{
  if (auto iter = match_if(s, pred)) {
    return iter;
  } else {
    if (!s.eof())
      cxt.on_expected(s.location(), cond, s.peek());
    else
      cxt.on_expected(cond);
    return {};
  }
}

// -------------------------------------------------------------------------- //
//                            Require element

// Returns the current token and advances the lexer to the
// next token. The current token is required to have kind k.
template<typename Stream, typename T>
Iterator_type<Stream>
require(Stream& s, T const& t)
{
  assert(s.peek() == t);
  return &s.get();
}

// Returns the current token and advances the lexer to the
// next token. The current token is required to have kind k.
template<typename Stream, typename P>
Iterator_type<Stream>
require_if(Stream& s, P pred)
{
  assert(pred(s.peek()));
  return &s.get();
}

} // namespace lingo

#endif
<commit_msg>Actually consume characters in get_n.<commit_after>// Copyright (c) 2015 Andrew Sutton
// All rights reserved

#ifndef LINGO_ALGORITHM_HPP
#define LINGO_ALGORITHM_HPP

// The algorithm module defines a set of matching algorithms suitable
// for use in lexers and parsers. These typically operate on character
// and token streams, and support matching against a variety of
// different patterns.
//
// Note that more specialized algorithms can be found in the lexing
// and parsing modules.

#include <algorithm>
#include <type_traits>
#include <iostream>

namespace lingo
{

// The iterator type of an aggregate.
template<typename T>
using Iterator_type = decltype(std::begin(std::declval<T>()));

// The value type of a stream.
template<typename T>
using Value_type = typename T::value_type;

// The argument type of a transform (lexer or parser).
template<typename T>
using Argument_type = typename T::argument_type;

// The result type of a transform (lexer or parser).
template<typename T>
using Result_type = typename T::result_type;

// Yields the return type of the given call expression.
template<typename Call>
using Result_of = typename std::result_of<Call>::type;

// A Range is a pair of iterators.
template<typename I>
struct Range
{
  Range()
    : first(), last(first)
  { }

  Range(I f, I l)
    : first(f), last(l)
  { }

  bool empty() const { return first == last; }
  I begin() const { return first; }
  I end() const   { return last; }

  // Converts to true iff not empty.
  explicit operator bool() const { return !empty(); }

  I first;
  I last;
};

// An alias used to constraint ranges over containers or streams.
template<typename T>
using Range_over = Range<Iterator_type<T>>;

// -------------------------------------------------------------------------- //
//                              Next element

// Returns true if the next element in the stream is equal to x.
template<typename Stream, typename T>
inline bool
next_element_is(Stream const& s, T const& x)
{
  return !s.eof() && s.peek() == x;
}

// Returns true if the next element in the stream is distinct
// from x.
template<typename Stream, typename T>
inline bool
next_element_is_not(Stream const& s, T const& x)
{
  return !s.eof() && s.peek() != x;
}

// Returns true if the nth element in the stream is equal to x.
template<typename Stream, typename T>
inline bool
nth_element_is(Stream const& s, int n, T const& x)
{
  return !s.eof() && s.peek(n) == x;
}

// Returns true if the next element satisfies the given predicate.
template<typename Stream, typename Pred>
inline bool
next_element_if_unguarded(Stream const& s, Pred pred)
{
  return pred(s.peek());
}

// Returns true if the next element satisfies the given predicate.
template<typename Stream, typename Pred>
inline bool
next_element_if(Stream const& s, Pred pred)
{
  return !s.eof() && pred(s.peek());
}

// -------------------------------------------------------------------------- //
//                         Next element in

// Returns false when there are no elements to match.
template<typename Stream>
inline bool
next_element_in(Stream const& s)
{
  return false;
}

// Returns true when the element matches in the set of elements
// given by [first, args...].
template<typename Stream, typename T, typename... Args>
inline bool
next_element_in(Stream const& s, T const& first, Args const&... args)
{
  if (next_element_is(s, first))
    return true;
  else
    return next_element_in(s, args...);
}

// -------------------------------------------------------------------------- //
//                         Next elements are

// Base case. Returns false.
template<typename Stream>
inline bool
next_elements_past_n_are(Stream const& s, int)
{
  return true;
}

// Rerusive step. Match the nth element and check the rest.
template<typename Stream, typename T, typename... Args>
inline bool
next_elements_past_n_are(Stream const& s, int n, T const& first, Args const&... args)
{
  if (nth_element_is(s, n, first))
    return next_elements_past_n_are(s, n + 1, args...);
  return false;
}

// Returns true when the next elements in match those given
// in by args.... Note that this operation requires lookahead
// of sizeof...(Args).
//
// If the required lookahead exceeds the buffer, this returns
// false.
template<typename Stream, typename T, typename... Args>
inline bool
next_elements_are(Stream const& s, Args const&... args)
{
  return next_elements_past_n_are(s, 0, args...);
}

// -------------------------------------------------------------------------- //
//                               Match
//
// The matching algorithms operate on streams. A stream `s` is required
// to support the following operations:
//
// - `s.eof()` -- returns true when the stream is at the end of file.
// - `s.peek()` -- returns a reference to the current element
// - `s.get()` -- returns a reference to the current element and advances
//
// Additionally, the iterator type must be the same `&s.get()`,
// and default constructing the iterator type must be contextually
// convertible to bool. This is typically a pointer into the stream.

// If the current element of the stream exactly matches t, then
// return an iterator to that element and advance the stream.
// Otherwise, return a null iterator.
//
// If the stream is past the end, then it does not match.
template<typename Stream, typename T>
inline Iterator_type<Stream>
match(Stream& s, T const& t)
{
  if (!s.eof() && s.peek() == t)
    return &s.get();
  else
    return {};
}

// If the current element stream satisfis the predicate `pred`,
// then return an iterator to that element. Otherwise, return the
// null iterator.
template<typename Stream, typename P>
inline Iterator_type<Stream>
match_if(Stream& s, P pred)
{
  if (!s.eof() && pred(s.peek()))
    return &s.get();
  else
    return {};
}

// -------------------------------------------------------------------------- //
//                            Match any

// The base case for match_any returns the null element.
template<typename Stream>
inline Iterator_type<Stream>
match_any(Stream& s)
{
  return {};
}

// If the current element in the stream matches any element
// in the argument pack [a, args...], return that element.
// Otherwise, return the null element.
template<typename Stream, typename A, typename... Args>
inline Iterator_type<Stream>
match_any(Stream& s, A const& a, Args const&... args)
{
  if (auto iter = match(s, a))
    return iter;
  else
    return match_any(s, args...);
}

// -------------------------------------------------------------------------- //
//                            Match any if

// The base case for match_any_if returns the null element.
template<typename Stream>
inline Iterator_type<Stream>
match_any_if(Stream& s)
{
  return {};
}

// If the current element in the stream satisfies one of
// the predicates in [pred, preds...], return the position of
// that element and advance the stream. Otherwise, return
// the null element.
template<typename Stream, typename P, typename... Preds>
inline Iterator_type<Stream>
match_any_if(Stream& s, P pred, Preds const&... preds)
{
  if (auto iter = match_if(s, pred))
    return iter;
  else
    return match_any_if(s, preds...);
}

// -------------------------------------------------------------------------- //
//                            Match all

// The base case for match_all returns current element.
template<typename Stream>
inline Iterator_type<Stream>
match_all(Stream& s)
{
  return s.begin();
}

// If the current element in the stream matches each element
// in the argument pack [a, args...], return a pointer past
// the last matched element. Otherwise, returns the null
// element.
template<typename Stream, typename A, typename... Args>
inline Iterator_type<Stream>
match_all(Stream& s, A const& a, Args const&... args)
{
  if (match(s, a))
    return match_all(s, args...);
  else
    return {};
}

// -------------------------------------------------------------------------- //
//                            Match range

// Returns an iterator range corresponding to a sequence
// of matched elements in the stream when the current element
// of the stream satisfies `pred`.
template<typename Stream, typename P>
inline Range_over<Stream>
match_range_after_first(Stream& s, P pred)
{
  assert(pred(s));
  Iterator_type<Stream> first = &s.get(); // Save the first position
  while (!s.eof() && pred(s)) {
    s.get();
  }
  Iterator_type<Stream> last = s.begin(); // Past the end of the range
  return {first, last};
}

// Returns an iterator range corresponding to a sequence
// of matched elements in the stream. If the current element
// is not in the set designated by match, the resulting range
// is empty.
template<typename Stream, typename P>
inline Range_over<Stream>
match_range(Stream& s, P pred)
{
  if (s.eof())
    return {s.end(), s.end()};
  if (!match(s))
    return {s.begin(), s.begin()};
  return match_range_after_first(s, match);
}

// -------------------------------------------------------------------------- //
//                            Get n elements

// Get n elements in the stream that satisfy the given
// predicate until reachin the first that does not. Returns
// an iterator to the first element discarded.
template<typename Stream>
inline Iterator_type<Stream>
get_n(Stream& s, int n)
{
  auto iter = s.begin();
  while (!s.eof() && n != 0) {
    s.get();
    --n;
  }
  return iter;
}

// -------------------------------------------------------------------------- //
//                              Discard if

// Discard all elements in the stream that satisfy the given
// predicate until reachin the first that does not. Returns
// an iterator to the first element discarded.
template<typename Stream, typename P>
inline Iterator_type<Stream>
discard_if(Stream& s, P pred)
{
  auto iter = s.begin();
  while (!s.eof() && pred(s))
    s.get();
  return iter;
}

// -------------------------------------------------------------------------- //
//                            Expect element
//
// The expect* algorithms are similar to the match algorithms except
// that diagnostics are emitted when the match fails. To support
// diagnostics, these algorithms also require the stream to provide
// support for source code locations. For any stream `s`
//
//    s.location()
//
// returns the current location in the underlying file or buffer. The
// only requirement for this type is that it is semiregular.
//
// To support generic diagnostics, the expect* algorithms require a
// context parameter, which defines the context of translation. The
// context must define the following functions:
//
//    cxt.on_expected(loc, t)
//    cxt.on_expected(loc, str)
//
// Where `loc` is a value returned by `s.location()`, `t` is an element
// in the stream and `str` is a C-string.

// If the current element matches of the stream the given kind,
// advance the stream, returning an iterator to the matched
// element. Otherwise, calls the on_expected error in the
// context.
template<typename Context, typename Stream, typename T>
Iterator_type<Stream>
expect(Context& cxt, Stream& s, T const& t)
{
  if (auto iter = match(s, t)) {
    return iter;
  } else {
    cxt.on_expected(s.location(), t);
    return {};
  }
}

// If the current element matches satisfies the predicate `pred`,
// return an iterator to that element and advance the stream.
// The `cond` string is used to provide feedback to the translation
// via the `on_expected` methods.
template<typename Context, typename Stream, typename P>
Iterator_type<Stream>
expect_if(Context& cxt, Stream& s, P pred, char const* cond)
{
  if (auto iter = match_if(s, pred)) {
    return iter;
  } else {
    if (!s.eof())
      cxt.on_expected(s.location(), cond, s.peek());
    else
      cxt.on_expected(cond);
    return {};
  }
}

// -------------------------------------------------------------------------- //
//                            Require element

// Returns the current token and advances the lexer to the
// next token. The current token is required to have kind k.
template<typename Stream, typename T>
Iterator_type<Stream>
require(Stream& s, T const& t)
{
  assert(s.peek() == t);
  return &s.get();
}

// Returns the current token and advances the lexer to the
// next token. The current token is required to have kind k.
template<typename Stream, typename P>
Iterator_type<Stream>
require_if(Stream& s, P pred)
{
  assert(pred(s.peek()));
  return &s.get();
}

} // namespace lingo

#endif
<|endoftext|>


<commit_before>#ifndef CH_NTB_EEDURO_DELTA_CONSTANTS_HPP
#define CH_NTB_EEDURO_DELTA_CONSTANTS_HPP

namespace eeduro {
	namespace delta {
		// Math constants
		constexpr double pi = 3.14159265359;

		// General constants
		constexpr unsigned int nofAxis = 4;

		// Electrical and mechanical parameters
		constexpr double i1524 = 387283.0/5103.0;	// gear ratio for the 3 main axis
		constexpr double i0816 = 319333.0/2673.0;	// gear ratio for the 4th axis
		constexpr double kM1524 = 11.4e-3; // [NM/A]
		constexpr double kM0816 = 8.98e-3; // [Nm/A]
		constexpr double RA1524 = 19.8; // [Ohm]
		constexpr double RA0816 = 106.4; // [Ohm]
		constexpr double jred = 0.000515154; // [kgm^2]
		constexpr double mtcp = 77.2e-3; // [kg]

		// Controller parameters
		constexpr double dt = 0.001; // [s]
		constexpr double D = 0.7;
		constexpr double w0 = 2 * pi * 20; // = 2 * pi * 1 / (2 * D * dt * pi);
		constexpr double kp = w0 / (2 * D);
		constexpr double kd = 2 * D * w0;

		constexpr double q012InitVoltage = 2.5; //[V]
		constexpr double q3InitVoltage = 1.5; //[V]

		constexpr double q012SafeMin = -2.0 * i1524;
		constexpr double q012SafeMax = 0.4 * i1524;
		constexpr double q3SafeMin = 0.0 * i0816;
		constexpr double q3SafeMax = 4.0 * i0816;

		constexpr double tcpReady_x = 0;
		constexpr double tcpReady_y = 0;
		constexpr double tcpReady_z = -0.01;
		constexpr double tcpReady_phi = 1.0;

		constexpr double q012homingOffset = 25.5 * 3.14159 / 180.0 * i1524;
		constexpr double q3homingOffset = 1.5 * i0816;

		constexpr double q012gearTorqueLimit = 0.3;
		constexpr double q3gearTorqueLimit = 0.025;
	}
}

#endif /* CH_NTB_EEDURO_DELTA_CONSTANTS_HPP */
<commit_msg>min/max range changed<commit_after>#ifndef CH_NTB_EEDURO_DELTA_CONSTANTS_HPP
#define CH_NTB_EEDURO_DELTA_CONSTANTS_HPP

namespace eeduro {
	namespace delta {
		// Math constants
		constexpr double pi = 3.14159265359;

		// General constants
		constexpr unsigned int nofAxis = 4;

		// Electrical and mechanical parameters
		constexpr double i1524 = 387283.0/5103.0;	// gear ratio for the 3 main axis
		constexpr double i0816 = 319333.0/2673.0;	// gear ratio for the 4th axis
		constexpr double kM1524 = 11.4e-3; // [NM/A]
		constexpr double kM0816 = 8.98e-3; // [Nm/A]
		constexpr double RA1524 = 19.8; // [Ohm]
		constexpr double RA0816 = 106.4; // [Ohm]
		constexpr double jred = 0.000515154; // [kgm^2]
		constexpr double mtcp = 77.2e-3; // [kg]

		// Controller parameters
		constexpr double dt = 0.001; // [s]
		constexpr double D = 0.7;
		constexpr double w0 = 2 * pi * 20; // = 2 * pi * 1 / (2 * D * dt * pi);
		constexpr double kp = w0 / (2 * D);
		constexpr double kd = 2 * D * w0;

		constexpr double q012InitVoltage = 2.5; //[V]
		constexpr double q3InitVoltage = 1.5; //[V]

		constexpr double q012SafeMin = -1.8 * i1524;
		constexpr double q012SafeMax = 0.4 * i1524;
		constexpr double q3SafeMin = -1.479 * i0816;
		constexpr double q3SafeMax = 1.479 * i0816;

		constexpr double tcpReady_x = 0;
		constexpr double tcpReady_y = 0;
		constexpr double tcpReady_z = -0.01;
		constexpr double tcpReady_phi = 1.0;

		constexpr double q012homingOffset = 25.5 * 3.14159 / 180.0 * i1524;
		constexpr double q3homingOffset = 1.483528611 * i0816;

		constexpr double q012gearTorqueLimit = 0.3;
		constexpr double q3gearTorqueLimit = 0.025;
	}
}

#endif /* CH_NTB_EEDURO_DELTA_CONSTANTS_HPP */
<|endoftext|>


<commit_before>#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <netdb.h>
#include <iostream>
#include <udt.h>
#include <sys/time.h>

#include "fluxpiclient.h"

using namespace std;

char buf[1024];
int buf_len = 1024;

int main(int argc, char * argv[])
{
    int len;

    //if(prepare_connection("192.168.10.100", "9000") == 0){
    if(prepare_connection("127.0.0.1", "9000") == 0){
        cout << " Connection error" << endl;
        return 0;
    }

    len = send_to_server(buf, buf_len);

    cout << "sent bytes: " << len << endl;

    clean_transmission();
    return 1;
}
<commit_msg>adding test code<commit_after>#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <netdb.h>
#include <iostream>
#include <udt.h>
#include <sys/time.h>

#include "fluxpiclient.h"

using namespace std;

char FRAME_MAGIC[] = {0x33, 0x44, 0x55, 0x44, 0x44, 0x77, 0x77, 0x27};
int MAGIC_LEN  = sizeof(FRAME_MAGIC);
char temp_frame[8];

char buf[1024*1024];
int buf_len = 1024*1024;

int main(int argc, char * argv[])
{
    int len;
    int framecount = 1000;

    if(prepare_connection("192.168.10.101", "9000") == 0){
    //if(prepare_connection("127.0.0.1", "9000") == 0){
        cout << " Connection error" << endl;
        return 0;
    }

    while(framecount-- > 0){
        len = send_to_server((char *)FRAME_MAGIC, MAGIC_LEN);
        cout << "sent bytes: " << len << endl;
        len = send_to_server(buf, buf_len);
        cout << "sent bytes: " << len << endl;
        usleep(10000);
    }

    char ch = getchar();
    cout << "done" << endl;

    clean_transmission();
    return 1;
}
<|endoftext|>


<commit_before>#include "linearcurve.h"

#include <cmath>

LinearCurve::LinearCurve()
{
    steps = 5;
}

LinearCurve::LinearCurve(const LinearCurve &x)
{
    this->ctrl = x.ctrl;
    this->steps = x.steps;
}

LinearCurve::LinearCurve(int steps)
{
    this->steps = steps;
}

LinearCurve::LinearCurve(int steps, const QList<QPoint> &ctrl)
{
    this->steps = steps;
    this->ctrl = ctrl;
}

double LinearCurve::value(double x)
{
    int lo = 1, hi = ctrl.count() - 1;
    int mid = (lo + hi) / 2;

    while (mid > 1 && lo < hi-1)
    {
        if (x <= ctrl.at(mid-1).x())
            hi = mid - 1;
        else if (x > ctrl.at(mid).x())
            lo = mid + 1;
        else
            break;
    }

    const QPoint &p1 = ctrl.at(mid-1);
    const QPoint &p2 = ctrl.at(mid);

    return p1.y() + (lround(x) - p1.x()) * (p2.y() - p1.y()) / (p2.x() - p1.x());
}

void LinearCurve::setControlPoints(const QList<QPoint> &ctrl)
{
    this->ctrl = ctrl;
}

QPolygon LinearCurve::getPolyline()
{
    QPolygon poly;
    for (int i = 0; i < ctrl.count(); ++i)
        poly.append(ctrl[i]);
    return poly;
}
<commit_msg>Linear interpolation fixed.<commit_after>#include "linearcurve.h"

#include <cmath>

LinearCurve::LinearCurve()
{
    steps = 5;
}

LinearCurve::LinearCurve(const LinearCurve &x)
{
    this->ctrl = x.ctrl;
    this->steps = x.steps;
}

LinearCurve::LinearCurve(int steps)
{
    this->steps = steps;
}

LinearCurve::LinearCurve(int steps, const QList<QPoint> &ctrl)
{
    this->steps = steps;
    this->ctrl = ctrl;
}

double LinearCurve::value(double x)
{
    int mid = 1;
    while (ctrl.at(mid).x() < x && mid < ctrl.count()-1)
        ++mid;

    const QPoint &p1 = ctrl.at(mid);
    const QPoint &p2 = ctrl.at(mid-1);

    return p1.y() + (lround(x) - p1.x()) * (p2.y() - p1.y()) / (p2.x() - p1.x());
}

void LinearCurve::setControlPoints(const QList<QPoint> &ctrl)
{
    this->ctrl = ctrl;
}

QPolygon LinearCurve::getPolyline()
{
    QPolygon poly;
    for (int i = 0; i < ctrl.count(); ++i)
        poly.append(ctrl[i]);
    return poly;
}
<|endoftext|>


<commit_before>/*
 *  datetime.cpp  -  date/time representation with optional date-only value
 *  Program:  kalarm
 *  (C) 2003 by David Jarvie  software@astrojar.org.uk
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  As a special exception, permission is given to link this program
 *  with any edition of Qt, and distribute the resulting executable,
 *  without including the source code for Qt in the source distribution.
 */

#include <kglobal.h>
#include <klocale.h>

#include "kalarmapp.h"
#include "preferences.h"
#include "datetime.h"

QTime DateTime::time() const
{
	return mDateOnly ? theApp()->preferences()->startOfDay() : mDateTime.time();
}

QDateTime DateTime::dateTime() const
{
	return mDateOnly ? QDateTime(mDateTime.date(), theApp()->preferences()->startOfDay()) : mDateTime;
}

QString DateTime::formatLocale(bool shortFormat) const
{
	if (mDateOnly)
		return KGlobal::locale()->formatDate(mDateTime.date(), shortFormat);
	else
		return KGlobal::locale()->formatDateTime(mDateTime, shortFormat);
}

bool operator==(const DateTime& dt1, const DateTime& dt2)
{
	if (dt1.mDateTime.date() != dt2.mDateTime.date())
		return false;
	if (dt1.mDateOnly && dt2.mDateOnly)
		return true;
	if (!dt1.mDateOnly && !dt2.mDateOnly)
		return dt1.mDateTime.time() == dt2.mDateTime.time();
	return (dt1.mDateOnly ? dt2.mDateTime.time() : dt1.mDateTime.time()) == theApp()->preferences()->startOfDay();
}

bool operator<(const DateTime& dt1, const DateTime& dt2)
{
	if (dt1.mDateTime.date() != dt2.mDateTime.date())
		return dt1.mDateTime.date() < dt2.mDateTime.date();
	if (dt1.mDateOnly && dt2.mDateOnly)
		return false;
	if (!dt1.mDateOnly && !dt2.mDateOnly)
		return dt1.mDateTime.time() < dt2.mDateTime.time();
	QTime t = theApp()->preferences()->startOfDay();
	if (dt1.mDateOnly)
		return t < dt2.mDateTime.time();
	return dt1.mDateTime.time() < t;
}
<commit_msg>KDE 2 compatibility<commit_after>/*
 *  datetime.cpp  -  date/time representation with optional date-only value
 *  Program:  kalarm
 *  (C) 2003 by David Jarvie  software@astrojar.org.uk
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  As a special exception, permission is given to link this program
 *  with any edition of Qt, and distribute the resulting executable,
 *  without including the source code for Qt in the source distribution.
 */
#include "kalarm.h"

#include <kglobal.h>
#include <klocale.h>

#include "kalarmapp.h"
#include "preferences.h"
#include "datetime.h"

QTime DateTime::time() const
{
	return mDateOnly ? theApp()->preferences()->startOfDay() : mDateTime.time();
}

QDateTime DateTime::dateTime() const
{
	return mDateOnly ? QDateTime(mDateTime.date(), theApp()->preferences()->startOfDay()) : mDateTime;
}

QString DateTime::formatLocale(bool shortFormat) const
{
	if (mDateOnly)
		return KGlobal::locale()->formatDate(mDateTime.date(), shortFormat);
	else
		return KGlobal::locale()->formatDateTime(mDateTime, shortFormat);
}

bool operator==(const DateTime& dt1, const DateTime& dt2)
{
	if (dt1.mDateTime.date() != dt2.mDateTime.date())
		return false;
	if (dt1.mDateOnly && dt2.mDateOnly)
		return true;
	if (!dt1.mDateOnly && !dt2.mDateOnly)
		return dt1.mDateTime.time() == dt2.mDateTime.time();
	return (dt1.mDateOnly ? dt2.mDateTime.time() : dt1.mDateTime.time()) == theApp()->preferences()->startOfDay();
}

bool operator<(const DateTime& dt1, const DateTime& dt2)
{
	if (dt1.mDateTime.date() != dt2.mDateTime.date())
		return dt1.mDateTime.date() < dt2.mDateTime.date();
	if (dt1.mDateOnly && dt2.mDateOnly)
		return false;
	if (!dt1.mDateOnly && !dt2.mDateOnly)
		return dt1.mDateTime.time() < dt2.mDateTime.time();
	QTime t = theApp()->preferences()->startOfDay();
	if (dt1.mDateOnly)
		return t < dt2.mDateTime.time();
	return dt1.mDateTime.time() < t;
}
<|endoftext|>