<commit_before>
/*
 *  client.cpp
 *
 *  Handles the client env.
 *
 *  Created by Ryan Faulkner on 2014-06-08
 *  Copyright (c) 2014. All rights reserved.
 */

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <assert.h>

#include "column_types.h"
#include "redis.h"
#include "md5.h"
#include "index.h"
#include "bayes.h"

#define REDISHOST "127.0.0.1"
#define REDISPORT 6379

using namespace std;

/** Test to ensure that redis keys are correctly returned */
void testRedisSet() {
    RedisHandler r;
    r.connect();
    r.write("foo", "bar");
}

/** Test to ensure that redis keys are correctly returned */
void testRedisGet() {
    RedisHandler r;
    r.connect();
    cout << endl << "VALUE FOR KEY foo" << endl;
    cout << r.read("foo") << endl << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisKeys() {
    RedisHandler r;
    std::vector<std::string> vec;

    r.connect();
    vec = r.keys("*");
    cout << "KEY LIST FOR *" << endl;
    for (std::vector<std::string>::iterator it = vec.begin() ; it != vec.end(); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisIO() {
    RedisHandler r;
    std::vector<string>* vec;
    std::string outTrue, outFalse = "";

    r.connect();
    r.write("test_key", "test value");
    outTrue = r.read("test_key");
    assert(std::strcmp(outTrue.c_str(), "test value") == 0);
    r.deleteKey("test_key");
    assert(!r.exists("test_key"));
}

/** Test to ensure that md5 hashing works */
void testMd5Hashing() {
    cout << endl << "md5 of 'mykey': " << md5("mykey") << endl;
}

/** Test to ensure that md5 hashing works */
void testRegexForTypes() {
    IntegerColumn ic;
    FloatColumn fc;
    assert(ic.validate("1981"));
    assert(fc.validate("5.2"));
    cout << "Passed regex tests." << endl;
}

/** Test to ensure that md5 hashing works */
void testOrderPairAlphaNumeric() {
    IndexHandler ih;
    assert(std::strcmp(ih.orderPairAlphaNumeric("b", "a").c_str(), "a_b") == 0);
    cout << "Passed orderPairAlphaNumeric tests." << endl;
}

/**
 * Test to ensure that relation entities are encoded properly
 */
void testJSONEntityEncoding() {

    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;

    fields_ent.push_back(std::make_pair(getColumnType("integer"), "a"));   // Create fields
    Entity e("test", fields_ent);
    ih.writeEntity(e);     // Create the entity
    ih.fetchEntity("test", json);           // Fetch the entity representation
    cout << "TEST ENTITY:" << endl << endl << json.toStyledString() << endl;

    // Assert that entity as read matches definition
    assert(std::strcmp(json["entity"].asCString(), "test") == 0 &&
            std::strcmp(json["fields"]["a"].asCString(), "integer") == 0 &&
            json["fields"]["_itemcount"].asInt() == 1
    );
    ih.removeEntity("test");                // Remove the entity
}

/**
 * Test to ensure that relation fields are encoded properly
 */
void testJSONRelationEncoding() {
    IndexHandler ih;
    std::vector<Json::Value> ret;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent_1;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent_2;
    std::vector<std::pair<std::string, std::string>> fields_rel_1;
    std::vector<std::pair<std::string, std::string>> fields_rel_2;

    // Popualate fields
    fields_ent_1.push_back(std::make_pair(getColumnType("integer"), "a"));
    fields_ent_2.push_back(std::make_pair(getColumnType("string"), "b"));
    fields_rel_1.push_back(std::make_pair("a", "1"));
    fields_rel_2.push_back(std::make_pair("b", "hello"));

    // Create entities
    Entity e1("test_1", fields_ent_1), e2("test_2", fields_ent_2);
    ih.writeEntity(e1);
    ih.writeEntity(e2);

    // Create relation in redis
    Relation r("test_1", "test_2", fields_rel_1, fields_rel_2);
    ih.writeRelation(r);

    // Fetch the entity representation
    ret = ih.fetchRelationPrefix("test_1", "test_2");
    cout << "TEST RELATION:" << endl << endl << ret[0].toStyledString() << endl;

    // Assert that entity as read matches definition
    assert(
        std::strcmp(ret[0]["entity_left"].asCString(), "test_1") == 0 &&
        std::strcmp(ret[0]["entity_right"].asCString(), "test_2") == 0 &&
        std::strcmp(ret[0]["fields_left"]["a"].asCString(), "1") == 0 &&
        std::strcmp(ret[0]["fields_right"]["b"].asCString(), "hello") == 0 &&
        ret[0]["fields_left"]["_itemcount"].asInt() == 1 &&
        ret[0]["fields_right"]["_itemcount"].asInt() == 1
    );
    ih.removeEntity("test_1");                // Remove the entity
    ih.removeEntity("test_2");                // Remove the entity
    ih.removeRelation(r);    // Remove the relation
}

/**
 *  Tests that parseEntityAssignField correctly flags invalid assignments to integer fields
 */
void testFieldAssignTypeMismatchInteger() {
    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    fields_ent.push_back(std::make_pair(getColumnType("integer"), "a"));   // Create fields
    Entity e("test", fields_ent);

    ih.writeEntity(e);     // Create the entity
    assert(
        ih.validateEntityFieldType("test", "a", "1") &&
        ih.validateEntityFieldType("test", "a", "12345") &&
        !ih.validateEntityFieldType("test", "a", "1.0") &&
        !ih.validateEntityFieldType("test", "a", "string")
    );
    ih.removeEntity("test");
}

/**
 *  Tests that parseEntityAssignField correctly flags invalid assignments to float fields
 */
void testFieldAssignTypeMismatchFloat() {
    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    fields_ent.push_back(std::make_pair(getColumnType("float"), "a"));   // Create fields
    Entity e("test", fields_ent);     // Create the entity

    ih.writeEntity(e);     // Create the entity
    assert(
        ih.validateEntityFieldType("test", "a", "1.2") &&
        ih.validateEntityFieldType("test", "a", "12.5") &&
        !ih.validateEntityFieldType("test", "a", "string")
    );
    ih.removeEntity("test");
}

/**
 *  Tests that parseEntityAssignField correctly flags invalid assignments to string fields
 */
void testFieldAssignTypeMismatchString() {
    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    fields_ent.push_back(std::make_pair(getColumnType("string"), "a"));   // Create fields
    Entity e("test", fields_ent);
    ih.writeEntity(e);     // Create the entity
    assert(
        ih.validateEntityFieldType("test", "a", "1") &&
        ih.validateEntityFieldType("test", "a", "12345") &&
        ih.validateEntityFieldType("test", "a", "string")
    );
    ih.removeEntity("test");
}

/**
 *  Tests that existsEntityField correctly flags when entity does not contain a field
 */
void testEntityDoesNotContainField() {
    // TODO - implement
}

/**
 *  Tests Bayes::computeMarginal function - ensure the marginal likelihood is correct
 */
void testComputeMarginal() {

    Bayes bayes;
    IndexHandler ih;
    std::vector<Json::Value> ret;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    std::vector<std::pair<std::string, std::string>> fields_rel;

    long num_relations = ih.getRelationCountTotal();

    // declare three entities
    Entity e1("_w", fields_ent), e2("_x", fields_ent), e3("_y", fields_ent), e4("_z", fields_ent);

    ih.writeEntity(e1);
    ih.writeEntity(e2);
    ih.writeEntity(e3);
    ih.writeEntity(e4);

    // construct a number of relations
    Relation r1("_x", "_y", fields_rel, fields_rel);
    Relation r2("_x", "_y", fields_rel, fields_rel);
    Relation r3("_x", "_z", fields_rel, fields_rel);
    Relation r4("_x", "_z", fields_rel, fields_rel);
    Relation r5("_w", "_y", fields_rel, fields_rel);

    ih.writeRelation(r1);
    ih.writeRelation(r2);
    ih.writeRelation(r3);
    ih.writeRelation(r4);
    ih.writeRelation(r5);

    // Ensure marginal likelihood reflects the number of relations that contain each entity
    valpair attrs;

    // TODO - fix computeMarginal seg fault
    cout << bayes.computeMarginal(e1.name, attrs) << endl;
    assert(bayes.computeMarginal(e1.name, attrs) == 4.0 / 5.0);
    assert(bayes.computeMarginal(e2.name, attrs) == 3.0 / 5.0);
    assert(bayes.computeMarginal(e3.name, attrs) == 2.0 / 5.0);
    assert(bayes.computeMarginal(e4.name, attrs) == 1.0 / 5.0);

    ih.removeEntity("_w");
    ih.removeEntity("_x");
    ih.removeEntity("_y");
    ih.removeEntity("_z");

    ih.removeRelation(r1);
    ih.removeRelation(r2);
    ih.removeRelation(r3);
    ih.removeRelation(r4);
    ih.removeRelation(r5);

    // Reset the relations count
    ih.setRelationCountTotal(num_relations);
}

/**
 *  Tests that removal of entities functions properly
 */
void testEntityRemoval() {
    // TODO - implement
}

/**
 *  Tests that removal of relations functions properly
 */
void testRelationRemoval() {
    // TODO - implement
}

/**
 *  Tests that removal of relations cascading on entities functions properly
 */
void testEntityCascadeRemoval() {
    // TODO - implement
}

int main() {
    cout << "-- TESTS BEGIN --" << endl << endl;

//    testRedisSet();
//    testRedisGet();
//    testRedisKeys();
//    md5Hashing();
//    testRedisIO();
//    testRegexForTypes();
//    testOrderPairAlphaNumeric();

    // testJSONEntityEncoding();
    // testJSONRelationEncoding();
    // testFieldAssignTypeMismatchInteger();
    // testFieldAssignTypeMismatchFloat();
    // testFieldAssignTypeMismatchString();
    testComputeMarginal();

    cout << endl << "-- TESTS END --" << endl;

    return 0;
}
<commit_msg>add test stub for relation filtering<commit_after>
/*
 *  client.cpp
 *
 *  Handles the client env.
 *
 *  Created by Ryan Faulkner on 2014-06-08
 *  Copyright (c) 2014. All rights reserved.
 */

#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <assert.h>

#include "column_types.h"
#include "redis.h"
#include "md5.h"
#include "index.h"
#include "bayes.h"

#define REDISHOST "127.0.0.1"
#define REDISPORT 6379

using namespace std;

/** Test to ensure that redis keys are correctly returned */
void testRedisSet() {
    RedisHandler r;
    r.connect();
    r.write("foo", "bar");
}

/** Test to ensure that redis keys are correctly returned */
void testRedisGet() {
    RedisHandler r;
    r.connect();
    cout << endl << "VALUE FOR KEY foo" << endl;
    cout << r.read("foo") << endl << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisKeys() {
    RedisHandler r;
    std::vector<std::string> vec;

    r.connect();
    vec = r.keys("*");
    cout << "KEY LIST FOR *" << endl;
    for (std::vector<std::string>::iterator it = vec.begin() ; it != vec.end(); ++it) {
        cout << *it << endl;
    }
    cout << endl;
}

/** Test to ensure that redis keys are correctly returned */
void testRedisIO() {
    RedisHandler r;
    std::vector<string>* vec;
    std::string outTrue, outFalse = "";

    r.connect();
    r.write("test_key", "test value");
    outTrue = r.read("test_key");
    assert(std::strcmp(outTrue.c_str(), "test value") == 0);
    r.deleteKey("test_key");
    assert(!r.exists("test_key"));
}

/** Test to ensure that md5 hashing works */
void testMd5Hashing() {
    cout << endl << "md5 of 'mykey': " << md5("mykey") << endl;
}

/** Test to ensure that md5 hashing works */
void testRegexForTypes() {
    IntegerColumn ic;
    FloatColumn fc;
    assert(ic.validate("1981"));
    assert(fc.validate("5.2"));
    cout << "Passed regex tests." << endl;
}

/** Test to ensure that md5 hashing works */
void testOrderPairAlphaNumeric() {
    IndexHandler ih;
    assert(std::strcmp(ih.orderPairAlphaNumeric("b", "a").c_str(), "a_b") == 0);
    cout << "Passed orderPairAlphaNumeric tests." << endl;
}

/**
 * Test to ensure that relation entities are encoded properly
 */
void testJSONEntityEncoding() {

    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;

    fields_ent.push_back(std::make_pair(getColumnType("integer"), "a"));   // Create fields
    Entity e("test", fields_ent);
    ih.writeEntity(e);     // Create the entity
    ih.fetchEntity("test", json);           // Fetch the entity representation
    cout << "TEST ENTITY:" << endl << endl << json.toStyledString() << endl;

    // Assert that entity as read matches definition
    assert(std::strcmp(json["entity"].asCString(), "test") == 0 &&
            std::strcmp(json["fields"]["a"].asCString(), "integer") == 0 &&
            json["fields"]["_itemcount"].asInt() == 1
    );
    ih.removeEntity("test");                // Remove the entity
}

/**
 * Test to ensure that relation fields are encoded properly
 */
void testJSONRelationEncoding() {
    IndexHandler ih;
    std::vector<Json::Value> ret;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent_1;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent_2;
    std::vector<std::pair<std::string, std::string>> fields_rel_1;
    std::vector<std::pair<std::string, std::string>> fields_rel_2;

    // Popualate fields
    fields_ent_1.push_back(std::make_pair(getColumnType("integer"), "a"));
    fields_ent_2.push_back(std::make_pair(getColumnType("string"), "b"));
    fields_rel_1.push_back(std::make_pair("a", "1"));
    fields_rel_2.push_back(std::make_pair("b", "hello"));

    // Create entities
    Entity e1("test_1", fields_ent_1), e2("test_2", fields_ent_2);
    ih.writeEntity(e1);
    ih.writeEntity(e2);

    // Create relation in redis
    Relation r("test_1", "test_2", fields_rel_1, fields_rel_2);
    ih.writeRelation(r);

    // Fetch the entity representation
    ret = ih.fetchRelationPrefix("test_1", "test_2");
    cout << "TEST RELATION:" << endl << endl << ret[0].toStyledString() << endl;

    // Assert that entity as read matches definition
    assert(
        std::strcmp(ret[0]["entity_left"].asCString(), "test_1") == 0 &&
        std::strcmp(ret[0]["entity_right"].asCString(), "test_2") == 0 &&
        std::strcmp(ret[0]["fields_left"]["a"].asCString(), "1") == 0 &&
        std::strcmp(ret[0]["fields_right"]["b"].asCString(), "hello") == 0 &&
        ret[0]["fields_left"]["_itemcount"].asInt() == 1 &&
        ret[0]["fields_right"]["_itemcount"].asInt() == 1
    );
    ih.removeEntity("test_1");                // Remove the entity
    ih.removeEntity("test_2");                // Remove the entity
    ih.removeRelation(r);    // Remove the relation
}

/**
 *  Tests that parseEntityAssignField correctly flags invalid assignments to integer fields
 */
void testFieldAssignTypeMismatchInteger() {
    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    fields_ent.push_back(std::make_pair(getColumnType("integer"), "a"));   // Create fields
    Entity e("test", fields_ent);

    ih.writeEntity(e);     // Create the entity
    assert(
        ih.validateEntityFieldType("test", "a", "1") &&
        ih.validateEntityFieldType("test", "a", "12345") &&
        !ih.validateEntityFieldType("test", "a", "1.0") &&
        !ih.validateEntityFieldType("test", "a", "string")
    );
    ih.removeEntity("test");
}

/**
 *  Tests that parseEntityAssignField correctly flags invalid assignments to float fields
 */
void testFieldAssignTypeMismatchFloat() {
    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    fields_ent.push_back(std::make_pair(getColumnType("float"), "a"));   // Create fields
    Entity e("test", fields_ent);     // Create the entity

    ih.writeEntity(e);     // Create the entity
    assert(
        ih.validateEntityFieldType("test", "a", "1.2") &&
        ih.validateEntityFieldType("test", "a", "12.5") &&
        !ih.validateEntityFieldType("test", "a", "string")
    );
    ih.removeEntity("test");
}

/**
 *  Tests that parseEntityAssignField correctly flags invalid assignments to string fields
 */
void testFieldAssignTypeMismatchString() {
    IndexHandler ih;
    Json::Value json;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    fields_ent.push_back(std::make_pair(getColumnType("string"), "a"));   // Create fields
    Entity e("test", fields_ent);
    ih.writeEntity(e);     // Create the entity
    assert(
        ih.validateEntityFieldType("test", "a", "1") &&
        ih.validateEntityFieldType("test", "a", "12345") &&
        ih.validateEntityFieldType("test", "a", "string")
    );
    ih.removeEntity("test");
}

/**
 *  Tests that existsEntityField correctly flags when entity does not contain a field
 */
void testEntityDoesNotContainField() {
    // TODO - implement
}

/**
 *  Tests Bayes::computeMarginal function - ensure the marginal likelihood is correct
 */
void testComputeMarginal() {

    Bayes bayes;
    IndexHandler ih;
    std::vector<Json::Value> ret;
    std::vector<std::pair<ColumnBase*, std::string>> fields_ent;
    std::vector<std::pair<std::string, std::string>> fields_rel;

    long num_relations = ih.getRelationCountTotal();

    // declare three entities
    Entity e1("_w", fields_ent), e2("_x", fields_ent), e3("_y", fields_ent), e4("_z", fields_ent);

    ih.writeEntity(e1);
    ih.writeEntity(e2);
    ih.writeEntity(e3);
    ih.writeEntity(e4);

    // construct a number of relations
    Relation r1("_x", "_y", fields_rel, fields_rel);
    Relation r2("_x", "_y", fields_rel, fields_rel);
    Relation r3("_x", "_z", fields_rel, fields_rel);
    Relation r4("_x", "_z", fields_rel, fields_rel);
    Relation r5("_w", "_y", fields_rel, fields_rel);

    ih.writeRelation(r1);
    ih.writeRelation(r2);
    ih.writeRelation(r3);
    ih.writeRelation(r4);
    ih.writeRelation(r5);

    // Ensure marginal likelihood reflects the number of relations that contain each entity
    valpair attrs;

    // TODO - fix computeMarginal seg fault
    cout << bayes.computeMarginal(e1.name, attrs) << endl;
    assert(bayes.computeMarginal(e1.name, attrs) == 4.0 / 5.0);
    assert(bayes.computeMarginal(e2.name, attrs) == 3.0 / 5.0);
    assert(bayes.computeMarginal(e3.name, attrs) == 2.0 / 5.0);
    assert(bayes.computeMarginal(e4.name, attrs) == 1.0 / 5.0);

    ih.removeEntity("_w");
    ih.removeEntity("_x");
    ih.removeEntity("_y");
    ih.removeEntity("_z");

    ih.removeRelation(r1);
    ih.removeRelation(r2);
    ih.removeRelation(r3);
    ih.removeRelation(r4);
    ih.removeRelation(r5);

    // Reset the relations count
    ih.setRelationCountTotal(num_relations);
}

/**
 *  Tests that removal of entities functions properly
 */
void testEntityRemoval() {
    // TODO - implement
}

/**
 *  Tests that removal of relations functions properly
 */
void testRelationRemoval() {
    // TODO - implement
}

/**
 *  Tests that removal of relations cascading on entities functions properly
 */
void testEntityCascadeRemoval() {
    // TODO - implement
}

/**
 *  Tests that the correct relations are filtered from a set
 */
void testRelationFiltering() {
    // TODO - implement
}

int main() {
    cout << "-- TESTS BEGIN --" << endl << endl;

//    testRedisSet();
//    testRedisGet();
//    testRedisKeys();
//    md5Hashing();
//    testRedisIO();
//    testRegexForTypes();
//    testOrderPairAlphaNumeric();

    // testJSONEntityEncoding();
    // testJSONRelationEncoding();
    // testFieldAssignTypeMismatchInteger();
    // testFieldAssignTypeMismatchFloat();
    // testFieldAssignTypeMismatchString();
    testComputeMarginal();

    cout << endl << "-- TESTS END --" << endl;

    return 0;
}
<|endoftext|>


<commit_before>/// \file multipath_mapper.cpp
///
/// unit tests for the multipath mapper

#include <iostream>
#include "json2pb.h"
#include "vg.pb.h"
#include "../multipath_mapper.hpp"
#include "catch.hpp"

namespace vg {
namespace unittest {

TEST_CASE( "MultipathMapper::read_coverage works", "[multipath][mapping][multipathmapper]" ) {

    // Make up some MEMs
    // GCSA range_type is just a pair of [start, end], so we can fake them.

    // This will actually own the MEMs
    vector<MaximalExactMatch> mems;

    // This will hold our MEMs and their start positions in the imaginary graph.
    vector<pair<const MaximalExactMatch*, pos_t>> mem_hits;

    // We need a fake read
    string read("GATTACA");

    SECTION("No hits cover no bases") {
        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == 0);
    }

    SECTION("A hit of zero length covers 0 bases") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin(), make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == 0);
    }

    SECTION("A hit that one-past-the-ends just after its start position covers 1 base") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin() + 1, make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == 1);
    }

    SECTION("A hit that ends at the end of the string covers the string") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.end(), make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == read.size());
    }

    SECTION("Two overlapping hits still only cover the string once") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin() + 5, make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        // Do it again
        mems.emplace_back(read.begin() + 2, read.end(), make_pair(6, 6), 1);
        mem_hits.emplace_back(&mems.back(), make_pos_t(888, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == read.size());
    }

    SECTION("Two abutting hits cover the string") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin() + 3, make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        // Do it again
        mems.emplace_back(read.begin() + 3, read.end(), make_pair(6, 6), 1);
        mem_hits.emplace_back(&mems.back(), make_pos_t(888, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == read.size());
    }

}

TEST_CASE( "MultipathMapper can map to a one-node graph", "[multipath][mapping][multipathmapper]" ) {

    string graph_json = R"({
        "node": [{"id": 1, "sequence": "GATTACA"}],
        "path": [
            {"name": "ref", "mapping": [
                {"position": {"node_id": 1}, "edit": [{"from_length": 7, "to_length": 7}]}
            ]}
        ]
    })";

    // Load the JSON
    Graph proto_graph;
    json2pb(proto_graph, graph_json.c_str(), graph_json.size());

    // Make it into a VG
    VG graph;
    graph.extend(proto_graph);

    // Configure GCSA temp directory to the system temp directory
    gcsa::TempFile::setDirectory(find_temp_dir());
    // And make it quiet
    gcsa::Verbosity::set(gcsa::Verbosity::SILENT);

    // Make pointers to fill in
    gcsa::GCSA* gcsaidx = nullptr;
    gcsa::LCPArray* lcpidx = nullptr;

    // Build the GCSA index
    graph.build_gcsa_lcp(gcsaidx, lcpidx, 16, false, false, 3);

    // Build the xg index
    xg::XG xg_index(proto_graph);

    // Make a multipath mapper to map against the graph.
    MultipathMapper mapper(&xg_index, gcsaidx, lcpidx);
    // Lower the max mapping quality so that it thinks it can find unambiguous mappings of
    // short sequences
    mapper.max_mapping_quality = 10;

    SECTION( "MultipathMapper can map a short fake read" ) {

        // Make the alignment
        string read = "GAT";
        Alignment aln;
        aln.set_sequence(read);

        // Have a list to fill with results
        vector<MultipathAlignment> results;

        // Align for just one alignment
        mapper.multipath_map(aln, results, 1);

        SECTION("there should be one alignment") {
            REQUIRE(results.size() == 1);
            auto& aligned = results.front();

            SECTION("which should have one subpath") {
                REQUIRE(aligned.subpath_size() == 1);
                auto& subpath = aligned.subpath(0);

                SECTION("which should have one mapping") {
                    REQUIRE(subpath.path().mapping_size() == 1);
                    auto& mapping = subpath.path().mapping(0);

                    SECTION("which should be at the start of node 1") {
                        REQUIRE(mapping.position().node_id() == 1);
                        REQUIRE(mapping.position().offset() == 0);
                        REQUIRE(mapping.position().is_reverse() == false);
                    }

                    SECTION("which should have one edit") {
                        REQUIRE(mapping.edit_size() == 1);
                        auto& edit = mapping.edit(0);

                        SECTION("which should be a length 3 perfect match") {
                            REQUIRE(edit.from_length() == 3);
                            REQUIRE(edit.to_length() == 3);
                            REQUIRE(edit.sequence() == "");
                        }
                    }
                }
            }
        }
    }

    SECTION( "MultipathMapper can map two tiny paired reads" ) {

        // Here are two reads in opposing, inward-facing directions
        Alignment read1, read2;
        read1.set_sequence("GAT");
        read2.set_sequence("ACA");

        // Have a list to fill with results
        vector<pair<MultipathAlignment, MultipathAlignment>> results;
        vector<pair<Alignment, Alignment>> buffer;

        // Align for just one pair of alignments
        mapper.multipath_map_paired(read1, read2, results, buffer, 1);

        SECTION("there should be one pair of alignments") {
            REQUIRE(results.size() == 1);
            auto& aligned1 = results.front().first;
            auto& aligned2 = results.front().second;

            SECTION("each read should have one subpath") {
                REQUIRE(aligned1.subpath_size() == 1);
                REQUIRE(aligned2.subpath_size() == 1);
                auto& subpath1 = aligned1.subpath(0);
                auto& subpath2 = aligned2.subpath(0);

                SECTION("each should have one mapping") {
                    REQUIRE(subpath1.path().mapping_size() == 1);
                    REQUIRE(subpath2.path().mapping_size() == 1);
                    auto& mapping1 = subpath1.path().mapping(0);
                    auto& mapping2 = subpath2.path().mapping(0);

                    SECTION("the first should be at the start of node 1") {
                        REQUIRE(mapping1.position().node_id() == 1);
                        REQUIRE(mapping1.position().offset() == 0);
                        REQUIRE(mapping1.position().is_reverse() == false);
                    }

                    SECTION("the second should be further along the same node") {
                        REQUIRE(mapping2.position().node_id() == 1);
                        REQUIRE(mapping2.position().offset() == 4);
                        REQUIRE(mapping2.position().is_reverse() == false);
                    }

                    SECTION("each should have one edit") {
                        REQUIRE(mapping1.edit_size() == 1);
                        REQUIRE(mapping2.edit_size() == 1);
                        auto& edit1 = mapping1.edit(0);
                        auto& edit2 = mapping2.edit(0);

                        SECTION("which should be a length 3 perfect match") {
                            REQUIRE(edit1.from_length() == 3);
                            REQUIRE(edit1.to_length() == 3);
                            REQUIRE(edit1.sequence() == "");
                            REQUIRE(edit2.from_length() == 3);
                            REQUIRE(edit2.to_length() == 3);
                            REQUIRE(edit2.sequence() == "");
                        }
                    }
                }
            }
        }

    }

    // Clean up the GCSA/LCP index
    delete gcsaidx;
    delete lcpidx;
}

}

}
<commit_msg>Fix test not to alter pointed-to vector<commit_after>/// \file multipath_mapper.cpp
///
/// unit tests for the multipath mapper

#include <iostream>
#include "json2pb.h"
#include "vg.pb.h"
#include "../multipath_mapper.hpp"
#include "catch.hpp"

namespace vg {
namespace unittest {

TEST_CASE( "MultipathMapper::read_coverage works", "[multipath][mapping][multipathmapper]" ) {

    // Make up some MEMs
    // GCSA range_type is just a pair of [start, end], so we can fake them.

    // This will actually own the MEMs
    vector<MaximalExactMatch> mems;

    // This will hold our MEMs and their start positions in the imaginary graph.
    vector<pair<const MaximalExactMatch*, pos_t>> mem_hits;

    // We need a fake read
    string read("GATTACA");

    SECTION("No hits cover no bases") {
        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == 0);
    }

    SECTION("A hit of zero length covers 0 bases") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin(), make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == 0);
    }

    SECTION("A hit that one-past-the-ends just after its start position covers 1 base") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin() + 1, make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == 1);
    }

    SECTION("A hit that ends at the end of the string covers the string") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.end(), make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        mem_hits.emplace_back(&mems.back(), make_pos_t(999, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == read.size());
    }

    SECTION("Two overlapping hits still only cover the string once") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin() + 5, make_pair(5, 5), 1);
        // Drop it on some arbitrary node
        // Do it again
        mems.emplace_back(read.begin() + 2, read.end(), make_pair(6, 6), 1);

        // Point into vector *after* it's done.
        mem_hits.emplace_back(&mems[0], make_pos_t(999, false, 3));
        mem_hits.emplace_back(&mems[1], make_pos_t(888, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == read.size());
    }

    SECTION("Two abutting hits cover the string") {
        // Make a MEM hit
        mems.emplace_back(read.begin(), read.begin() + 3, make_pair(5, 5), 1);
        // Do it again
        mems.emplace_back(read.begin() + 3, read.end(), make_pair(6, 6), 1);

        // Point into vector *after* it's done.
        mem_hits.emplace_back(&mems[0], make_pos_t(999, false, 3));
        mem_hits.emplace_back(&mems[1], make_pos_t(888, false, 3));

        auto covered = MultipathMapper::read_coverage(mem_hits);
        REQUIRE(covered == read.size());
    }

}

TEST_CASE( "MultipathMapper can map to a one-node graph", "[multipath][mapping][multipathmapper]" ) {

    string graph_json = R"({
        "node": [{"id": 1, "sequence": "GATTACA"}],
        "path": [
            {"name": "ref", "mapping": [
                {"position": {"node_id": 1}, "edit": [{"from_length": 7, "to_length": 7}]}
            ]}
        ]
    })";

    // Load the JSON
    Graph proto_graph;
    json2pb(proto_graph, graph_json.c_str(), graph_json.size());

    // Make it into a VG
    VG graph;
    graph.extend(proto_graph);

    // Configure GCSA temp directory to the system temp directory
    gcsa::TempFile::setDirectory(find_temp_dir());
    // And make it quiet
    gcsa::Verbosity::set(gcsa::Verbosity::SILENT);

    // Make pointers to fill in
    gcsa::GCSA* gcsaidx = nullptr;
    gcsa::LCPArray* lcpidx = nullptr;

    // Build the GCSA index
    graph.build_gcsa_lcp(gcsaidx, lcpidx, 16, false, false, 3);

    // Build the xg index
    xg::XG xg_index(proto_graph);

    // Make a multipath mapper to map against the graph.
    MultipathMapper mapper(&xg_index, gcsaidx, lcpidx);
    // Lower the max mapping quality so that it thinks it can find unambiguous mappings of
    // short sequences
    mapper.max_mapping_quality = 10;

    SECTION( "MultipathMapper can map a short fake read" ) {

        // Make the alignment
        string read = "GAT";
        Alignment aln;
        aln.set_sequence(read);

        // Have a list to fill with results
        vector<MultipathAlignment> results;

        // Align for just one alignment
        mapper.multipath_map(aln, results, 1);

        SECTION("there should be one alignment") {
            REQUIRE(results.size() == 1);
            auto& aligned = results.front();

            SECTION("which should have one subpath") {
                REQUIRE(aligned.subpath_size() == 1);
                auto& subpath = aligned.subpath(0);

                SECTION("which should have one mapping") {
                    REQUIRE(subpath.path().mapping_size() == 1);
                    auto& mapping = subpath.path().mapping(0);

                    SECTION("which should be at the start of node 1") {
                        REQUIRE(mapping.position().node_id() == 1);
                        REQUIRE(mapping.position().offset() == 0);
                        REQUIRE(mapping.position().is_reverse() == false);
                    }

                    SECTION("which should have one edit") {
                        REQUIRE(mapping.edit_size() == 1);
                        auto& edit = mapping.edit(0);

                        SECTION("which should be a length 3 perfect match") {
                            REQUIRE(edit.from_length() == 3);
                            REQUIRE(edit.to_length() == 3);
                            REQUIRE(edit.sequence() == "");
                        }
                    }
                }
            }
        }
    }

    SECTION( "MultipathMapper can map two tiny paired reads" ) {

        // Here are two reads in opposing, inward-facing directions
        Alignment read1, read2;
        read1.set_sequence("GAT");
        read2.set_sequence("ACA");

        // Have a list to fill with results
        vector<pair<MultipathAlignment, MultipathAlignment>> results;
        vector<pair<Alignment, Alignment>> buffer;

        // Align for just one pair of alignments
        mapper.multipath_map_paired(read1, read2, results, buffer, 1);

        SECTION("there should be one pair of alignments") {
            REQUIRE(results.size() == 1);
            auto& aligned1 = results.front().first;
            auto& aligned2 = results.front().second;

            SECTION("each read should have one subpath") {
                REQUIRE(aligned1.subpath_size() == 1);
                REQUIRE(aligned2.subpath_size() == 1);
                auto& subpath1 = aligned1.subpath(0);
                auto& subpath2 = aligned2.subpath(0);

                SECTION("each should have one mapping") {
                    REQUIRE(subpath1.path().mapping_size() == 1);
                    REQUIRE(subpath2.path().mapping_size() == 1);
                    auto& mapping1 = subpath1.path().mapping(0);
                    auto& mapping2 = subpath2.path().mapping(0);

                    SECTION("the first should be at the start of node 1") {
                        REQUIRE(mapping1.position().node_id() == 1);
                        REQUIRE(mapping1.position().offset() == 0);
                        REQUIRE(mapping1.position().is_reverse() == false);
                    }

                    SECTION("the second should be further along the same node") {
                        REQUIRE(mapping2.position().node_id() == 1);
                        REQUIRE(mapping2.position().offset() == 4);
                        REQUIRE(mapping2.position().is_reverse() == false);
                    }

                    SECTION("each should have one edit") {
                        REQUIRE(mapping1.edit_size() == 1);
                        REQUIRE(mapping2.edit_size() == 1);
                        auto& edit1 = mapping1.edit(0);
                        auto& edit2 = mapping2.edit(0);

                        SECTION("which should be a length 3 perfect match") {
                            REQUIRE(edit1.from_length() == 3);
                            REQUIRE(edit1.to_length() == 3);
                            REQUIRE(edit1.sequence() == "");
                            REQUIRE(edit2.from_length() == 3);
                            REQUIRE(edit2.to_length() == 3);
                            REQUIRE(edit2.sequence() == "");
                        }
                    }
                }
            }
        }

    }

    // Clean up the GCSA/LCP index
    delete gcsaidx;
    delete lcpidx;
}

}

}
<|endoftext|>


<commit_before>// Lesson 13.cpp : Defines the entry point for the console application.

#include <render_framework\render_framework.h>
#pragma comment (lib , "Render Framework" )

using namespace std;
using namespace glm;
using namespace render_framework;

int main()
{
	// Initialize the renderer
	if (!renderer::get_instance().initialise()) return -1;

	// Set the clear colour to cyan
	glClearColor(0.0f, 1.0f, 1.0f, 1.0f);

	/* Set the projection matrix */
	// First get the aspect ratio (width/height)
	float aspect = (float)renderer::get_instance().get_screen_width() /
					(float)renderer::get_instance().get_screen_width();
	// Use this to create projection matrix
	auto projection = perspective(
						degrees(quarter_pi<float>()),	// FOV
						aspect,							// Aspect ratio
						2.414f,							// Near plane
						10000.0f);						// Far plane
	// Set the projection matrix
	renderer::get_instance().set_projection(projection);

	// Set the view matrix
	auto view = lookAt(
					vec3(20.0f, 20.0f, 20.0f),	// Camera position
					vec3(0.0f, 0.0f, 0.0f),		// Target
					vec3(0.0f, 1.0f, 0.0f));	// Up vector
	renderer::get_instance().set_view(view);

	// Create Cube
	auto object = geometry_builder::create_tetrahedron();

	// Main render loop
	while (renderer::get_instance().is_running())
	{
		// Check if running
		if (renderer::get_instance().begin_render())
		{
			// Render Cube
			renderer::get_instance().render(object);

			// End the render
			renderer::get_instance().end_render();
		}
	}
}

<commit_msg>Create pyramid<commit_after>// Lesson 13.cpp : Defines the entry point for the console application.

#include <render_framework\render_framework.h>
#pragma comment (lib , "Render Framework" )

using namespace std;
using namespace glm;
using namespace render_framework;

int main()
{
	// Initialize the renderer
	if (!renderer::get_instance().initialise()) return -1;

	// Set the clear colour to cyan
	glClearColor(0.0f, 1.0f, 1.0f, 1.0f);

	/* Set the projection matrix */
	// First get the aspect ratio (width/height)
	float aspect = (float)renderer::get_instance().get_screen_width() /
					(float)renderer::get_instance().get_screen_width();
	// Use this to create projection matrix
	auto projection = perspective(
						degrees(quarter_pi<float>()),	// FOV
						aspect,							// Aspect ratio
						2.414f,							// Near plane
						10000.0f);						// Far plane
	// Set the projection matrix
	renderer::get_instance().set_projection(projection);

	// Set the view matrix
	auto view = lookAt(
					vec3(20.0f, 20.0f, 20.0f),	// Camera position
					vec3(0.0f, 0.0f, 0.0f),		// Target
					vec3(0.0f, 1.0f, 0.0f));	// Up vector
	renderer::get_instance().set_view(view);

	// Create Object
	auto object = geometry_builder::create_pyramid();

	// Main render loop
	while (renderer::get_instance().is_running())
	{
		// Check if running
		if (renderer::get_instance().begin_render())
		{
			// Render Cube
			renderer::get_instance().render(object);

			// End the render
			renderer::get_instance().end_render();
		}
	}
}

<|endoftext|>


<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libdui.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <DuiWidget>
#include "duiwidgetrecycler.h"
#include "duiwidgetrecycler_p.h"

DuiWidgetRecyclerPrivate::DuiWidgetRecyclerPrivate()
    : widgetCount(0), maxWidgetCount(10)
{
}

DuiWidgetRecyclerPrivate::~DuiWidgetRecyclerPrivate()
{
    qDeleteAll(widgets);
}

void DuiWidgetRecyclerPrivate::resetWidgetState(DuiWidget *widget)
{
    widget->setVisible(false);
    //widget->setParentItem(NULL);
    //widget->setParentLayoutItem(NULL);
}

bool DuiWidgetRecyclerPrivate::hasEnoughSpaceFor(DuiWidget *widget)
{
    return widgets.count(widget->metaObject()->className()) < maxWidgetCount;
}

void DuiWidgetRecyclerPrivate::put(DuiWidget *widget)
{
    widgets.insert(widget->metaObject()->className(), widget);
}

DuiWidget *DuiWidgetRecyclerPrivate::take(const QString &className)
{
    return widgets.take(className);
}

DuiWidgetRecycler::DuiWidgetRecycler()
    : d_ptr(new DuiWidgetRecyclerPrivate())
{
}

DuiWidgetRecycler::~DuiWidgetRecycler()
{
    delete d_ptr;
}

DuiWidgetRecycler *DuiWidgetRecycler::instance()
{
    static DuiWidgetRecycler recycler;
    return &recycler;
}

void DuiWidgetRecycler::setMaxItemsPerClass(int count)
{
    d_ptr->maxWidgetCount = count;
}

int DuiWidgetRecycler::maxItemsPerClass() const
{
    return d_ptr->maxWidgetCount;
}

void DuiWidgetRecycler::recycle(DuiWidget *widget)
{
    if (widget) {
        if (d_ptr->hasEnoughSpaceFor(widget)) {
            d_ptr->resetWidgetState(widget);
            d_ptr->put(widget);
        } else {
            delete widget;
        }
    }
}

DuiWidget *DuiWidgetRecycler::take(const QString &className)
{
    DuiWidget *widget = d_ptr->take(className);

    return widget;
}
<commit_msg>Changes: DuiWidgetRecycler doesn't hide recycled item anymore, it just moves it outside of the screen. setVisible() is quite expensive operation in QT.<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libdui.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <DuiWidget>
#include "duiwidgetrecycler.h"
#include "duiwidgetrecycler_p.h"

DuiWidgetRecyclerPrivate::DuiWidgetRecyclerPrivate()
    : widgetCount(0), maxWidgetCount(10)
{
}

DuiWidgetRecyclerPrivate::~DuiWidgetRecyclerPrivate()
{
    qDeleteAll(widgets);
}

void DuiWidgetRecyclerPrivate::resetWidgetState(DuiWidget *widget)
{
    // lets just move it far far away, so that noone can see it
    widget->setPos(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX);
    //widget->setVisible(false);
    //widget->setParentItem(NULL);
    //widget->setParentLayoutItem(NULL);
}

bool DuiWidgetRecyclerPrivate::hasEnoughSpaceFor(DuiWidget *widget)
{
    return widgets.count(widget->metaObject()->className()) < maxWidgetCount;
}

void DuiWidgetRecyclerPrivate::put(DuiWidget *widget)
{
    widgets.insert(widget->metaObject()->className(), widget);
}

DuiWidget *DuiWidgetRecyclerPrivate::take(const QString &className)
{
    return widgets.take(className);
}

DuiWidgetRecycler::DuiWidgetRecycler()
    : d_ptr(new DuiWidgetRecyclerPrivate())
{
}

DuiWidgetRecycler::~DuiWidgetRecycler()
{
    delete d_ptr;
}

DuiWidgetRecycler *DuiWidgetRecycler::instance()
{
    static DuiWidgetRecycler recycler;
    return &recycler;
}

void DuiWidgetRecycler::setMaxItemsPerClass(int count)
{
    d_ptr->maxWidgetCount = count;
}

int DuiWidgetRecycler::maxItemsPerClass() const
{
    return d_ptr->maxWidgetCount;
}

void DuiWidgetRecycler::recycle(DuiWidget *widget)
{
    if (widget) {
        if (d_ptr->hasEnoughSpaceFor(widget)) {
            d_ptr->resetWidgetState(widget);
            d_ptr->put(widget);
        } else {
            delete widget;
        }
    }
}

DuiWidget *DuiWidgetRecycler::take(const QString &className)
{
    DuiWidget *widget = d_ptr->take(className);

    return widget;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>
#include <iomanip>
#include <sstream>
#define MAX_SIZE 256
using namespace std;
// https://memset.wordpress.com/2010/10/06/using-sha1-function/
// http://stackoverflow.com/questions/11765522/how-do-i-write-this-in-cout-c
string print_hex(unsigned char *bs, unsigned int n) {
    string ret_val = "";
    for (int i = 0; i < n; i++) {
        stringstream ss;
        ss << hex << static_cast<int>(bs[i]);
        ret_val += ss.str();
    }
    return ret_val;
}
int main(int argc, char ** argv) {
    if ( argc != 2 ) {
        cerr << "Usage: " << argv[0] << " <string>" << endl;
        exit(EXIT_FAILURE);
    }
    char * tmp = new char[MAX_SIZE];
    unsigned char temp[SHA512_DIGEST_LENGTH];
 	strncpy(tmp, argv[1], MAX_SIZE);
    memset(temp, 0x0, SHA512_DIGEST_LENGTH);
    SHA512((unsigned char *)argv[1], strlen(argv[1]), temp);
    cout << "SHA512 of " << tmp << " is " << print_hex(temp, sizeof(temp)) << endl;
    return 0;
}
<commit_msg>Fixed Buffer Overflow Bug<commit_after>#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/sha.h>
#include <iomanip>
#include <sstream>
#define MAX_SIZE 256
using namespace std;
// https://memset.wordpress.com/2010/10/06/using-sha1-function/
// http://stackoverflow.com/questions/11765522/how-do-i-write-this-in-cout-c
string print_hex(unsigned char *bs, unsigned int n) {
    string ret_val = "";
    for (int i = 0; i < n; i++) {
        stringstream ss;
        ss << hex << static_cast<int>(bs[i]);
        ret_val += ss.str();
    }
    return ret_val;
}
int main(int argc, char ** argv) {
    if ( argc != 2 ) {
        cerr << "Usage: " << argv[0] << " <string>" << endl;
        exit(EXIT_FAILURE);
    }
    char * tmp = new char[MAX_SIZE];
    unsigned char temp[SHA512_DIGEST_LENGTH];
 	strncpy(tmp, argv[1], MAX_SIZE);
    memset(temp, 0x0, SHA512_DIGEST_LENGTH);
    SHA512((unsigned char *)tmp, strlen(tmp), temp);
    cout << "SHA512 of " << tmp << " is " << print_hex(temp, sizeof(temp)) << endl;
    return 0;
}
<|endoftext|>


<commit_before>#include "widgets/helper/splitinput.hpp"
#include "singletons/commandmanager.hpp"
#include "singletons/completionmanager.hpp"
#include "singletons/ircmanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "util/layoutcreator.hpp"
#include "widgets/notebook.hpp"
#include "widgets/split.hpp"
#include "widgets/splitcontainer.hpp"

#include <QCompleter>
#include <QPainter>

namespace chatterino {
namespace widgets {

SplitInput::SplitInput(Split *_chatWidget)
    : BaseWidget(_chatWidget)
    , chatWidget(_chatWidget)
{
    this->initLayout();

    // auto completion
    auto completer = new QCompleter(
        singletons::CompletionManager::getInstance().createModel(this->chatWidget->channelName));

    this->ui.textEdit->setCompleter(completer);

    // misc
    this->installKeyPressedEvent();
    this->themeRefreshEvent();
    this->scaleChangedEvent(this->getScale());
}

void SplitInput::initLayout()
{
    auto &fontManager = singletons::FontManager::getInstance();
    util::LayoutCreator<SplitInput> layoutCreator(this);

    auto layout = layoutCreator.setLayoutType<QHBoxLayout>().withoutMargin().assign(&this->ui.hbox);

    // input
    auto textEdit = layout.emplace<ResizingTextEdit>().assign(&this->ui.textEdit);
    connect(textEdit.getElement(), &ResizingTextEdit::textChanged, this,
            &SplitInput::editTextChanged);

    // right box
    auto box = layout.emplace<QVBoxLayout>().withoutMargin();
    box->setSpacing(0);
    {
        auto textEditLength = box.emplace<QLabel>().assign(&this->ui.textEditLength);
        textEditLength->setAlignment(Qt::AlignRight);

        box->addStretch(1);
        box.emplace<RippleEffectLabel>().assign(&this->ui.emoteButton);
    }

    this->ui.emoteButton->getLabel().setTextFormat(Qt::RichText);

    // ---- misc

    // set edit font
    this->ui.textEdit->setFont(
        fontManager.getFont(singletons::FontManager::Type::Medium, this->getScale()));

    this->managedConnections.emplace_back(fontManager.fontChanged.connect([this, &fontManager]() {
        this->ui.textEdit->setFont(
            fontManager.getFont(singletons::FontManager::Type::Medium, this->getScale()));
    }));

    // open emote popup
    QObject::connect(this->ui.emoteButton, &RippleEffectLabel::clicked, [this] {
        if (!this->emotePopup) {
            this->emotePopup = std::make_unique<EmotePopup>(this->themeManager);
            this->emotePopup->linkClicked.connect([this](const messages::Link &link) {
                if (link.getType() == messages::Link::InsertText) {
                    this->insertText(link.getValue());
                }
            });
        }

        this->emotePopup->resize((int)(300 * this->emotePopup->getScale()),
                                 (int)(500 * this->emotePopup->getScale()));
        this->emotePopup->loadChannel(this->chatWidget->getChannel());
        this->emotePopup->show();
    });

    // clear channelview selection when selecting in the input
    QObject::connect(this->ui.textEdit, &QTextEdit::copyAvailable, [this](bool available) {
        if (available) {
            this->chatWidget->view.clearSelection();
        }
    });

    // textEditLength visibility
    singletons::SettingManager::getInstance().showMessageLength.connect(
        [this](const bool &value, auto) { this->ui.textEditLength->setHidden(!value); },
        this->managedConnections);
}

void SplitInput::scaleChangedEvent(float scale)
{
    // update the icon size of the emote button
    QString text = "";
    text.replace("xD", QString::number((int)12 * scale));

    this->ui.emoteButton->getLabel().setText(text);
    this->ui.emoteButton->setFixedHeight((int)18 * scale);

    // set maximum height
    this->setMaximumHeight((int)(150 * this->getScale()));

    this->themeRefreshEvent();
}

void SplitInput::themeRefreshEvent()
{
    QPalette palette;

    palette.setColor(QPalette::Foreground, this->themeManager.splits.input.text);

    this->ui.textEditLength->setPalette(palette);

    this->ui.textEdit->setStyleSheet(this->themeManager.splits.input.styleSheet);

    this->ui.hbox->setMargin((this->themeManager.isLightTheme() ? 4 : 2) * this->getScale());
}

void SplitInput::installKeyPressedEvent()
{
    this->ui.textEdit->keyPressed.connect([this](QKeyEvent *event) {
        if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
            auto c = this->chatWidget->getChannel();
            if (c == nullptr) {
                return;
            }
            QString message = ui.textEdit->toPlainText();

            QString sendMessage =
                singletons::CommandManager::getInstance().execCommand(message, c, false);
            sendMessage = sendMessage.replace('\n', ' ');

            c->sendMessage(sendMessage);
            this->prevMsg.append(message);

            event->accept();
            if (!(event->modifiers() == Qt::ControlModifier)) {
                this->ui.textEdit->setText(QString());
                this->prevIndex = 0;
            } else if (this->ui.textEdit->toPlainText() ==
                       this->prevMsg.at(this->prevMsg.size() - 1)) {
                this->prevMsg.removeLast();
            }
            this->prevIndex = this->prevMsg.size();
        } else if (event->key() == Qt::Key_Up) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX;
                int reqY = page->lastRequestedY[reqX] - 1;

                qDebug() << "Alt+Down to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            } else {
                if (this->prevMsg.size() && this->prevIndex) {
                    this->prevIndex--;
                    this->ui.textEdit->setText(this->prevMsg.at(this->prevIndex));
                }
            }
        } else if (event->key() == Qt::Key_Down) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX;
                int reqY = page->lastRequestedY[reqX] + 1;

                qDebug() << "Alt+Down to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            } else {
                if (this->prevIndex != (this->prevMsg.size() - 1) &&
                    this->prevIndex != this->prevMsg.size()) {
                    this->prevIndex++;
                    this->ui.textEdit->setText(this->prevMsg.at(this->prevIndex));
                } else {
                    this->prevIndex = this->prevMsg.size();
                    this->ui.textEdit->setText(QString());
                }
            }
        } else if (event->key() == Qt::Key_Left) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX - 1;
                int reqY = page->lastRequestedY[reqX];

                qDebug() << "Alt+Left to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            }
        } else if (event->key() == Qt::Key_Right) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX + 1;
                int reqY = page->lastRequestedY[reqX];

                qDebug() << "Alt+Right to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            }
        } else if (event->key() == Qt::Key_Tab) {
            if (event->modifiers() == Qt::ControlModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                Notebook *notebook = static_cast<Notebook *>(page->parentWidget());

                notebook->nextTab();
            }
        } else if (event->key() == Qt::Key_Backtab) {
            if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                Notebook *notebook = static_cast<Notebook *>(page->parentWidget());

                notebook->previousTab();
            }
        } else if (event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier) {
            if (this->chatWidget->view.hasSelection()) {
                this->chatWidget->doCopy();
                event->accept();
            }
        }
    });
}

void SplitInput::clearSelection()
{
    QTextCursor c = this->ui.textEdit->textCursor();

    c.setPosition(c.position());
    c.setPosition(c.position(), QTextCursor::KeepAnchor);

    this->ui.textEdit->setTextCursor(c);
}

QString SplitInput::getInputText() const
{
    return this->ui.textEdit->toPlainText();
}

void SplitInput::insertText(const QString &text)
{
    this->ui.textEdit->insertPlainText(text);
}

void SplitInput::editTextChanged()
{
    // set textLengthLabel value
    QString text = this->ui.textEdit->toPlainText();

    this->textChanged.invoke(text);

    text = text.trimmed();
    static QRegularExpression spaceRegex("\\s\\s+");
    text = text.replace(spaceRegex, " ");

    text = singletons::CommandManager::getInstance().execCommand(
        text, this->chatWidget->getChannel(), true);

    QString labelText;

    if (text.length() == 0) {
        labelText = "";
    } else {
        labelText = QString::number(text.length());
    }

    this->ui.textEditLength->setText(labelText);
}

void SplitInput::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    painter.fillRect(this->rect(), this->themeManager.splits.input.background);

    QPen pen(this->themeManager.splits.input.border);
    if (this->themeManager.isLightTheme()) {
        pen.setWidth((int)(6 * this->getScale()));
    }
    painter.setPen(pen);
    painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
}

void SplitInput::resizeEvent(QResizeEvent *)
{
    if (this->height() == this->maximumHeight()) {
        this->ui.textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    } else {
        this->ui.textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    }
}

void SplitInput::mousePressEvent(QMouseEvent *)
{
    this->chatWidget->giveFocus(Qt::MouseFocusReason);
}

}  // namespace widgets
}  // namespace chatterino
<commit_msg>fixed #252 clicking emotes in the emote popup<commit_after>#include "widgets/helper/splitinput.hpp"
#include "singletons/commandmanager.hpp"
#include "singletons/completionmanager.hpp"
#include "singletons/ircmanager.hpp"
#include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp"
#include "util/layoutcreator.hpp"
#include "widgets/notebook.hpp"
#include "widgets/split.hpp"
#include "widgets/splitcontainer.hpp"

#include <QCompleter>
#include <QPainter>

namespace chatterino {
namespace widgets {

SplitInput::SplitInput(Split *_chatWidget)
    : BaseWidget(_chatWidget)
    , chatWidget(_chatWidget)
{
    this->initLayout();

    // auto completion
    auto completer = new QCompleter(
        singletons::CompletionManager::getInstance().createModel(this->chatWidget->channelName));

    this->ui.textEdit->setCompleter(completer);

    // misc
    this->installKeyPressedEvent();
    this->themeRefreshEvent();
    this->scaleChangedEvent(this->getScale());
}

void SplitInput::initLayout()
{
    auto &fontManager = singletons::FontManager::getInstance();
    util::LayoutCreator<SplitInput> layoutCreator(this);

    auto layout = layoutCreator.setLayoutType<QHBoxLayout>().withoutMargin().assign(&this->ui.hbox);

    // input
    auto textEdit = layout.emplace<ResizingTextEdit>().assign(&this->ui.textEdit);
    connect(textEdit.getElement(), &ResizingTextEdit::textChanged, this,
            &SplitInput::editTextChanged);

    // right box
    auto box = layout.emplace<QVBoxLayout>().withoutMargin();
    box->setSpacing(0);
    {
        auto textEditLength = box.emplace<QLabel>().assign(&this->ui.textEditLength);
        textEditLength->setAlignment(Qt::AlignRight);

        box->addStretch(1);
        box.emplace<RippleEffectLabel>().assign(&this->ui.emoteButton);
    }

    this->ui.emoteButton->getLabel().setTextFormat(Qt::RichText);

    // ---- misc

    // set edit font
    this->ui.textEdit->setFont(
        fontManager.getFont(singletons::FontManager::Type::Medium, this->getScale()));

    this->managedConnections.emplace_back(fontManager.fontChanged.connect([this, &fontManager]() {
        this->ui.textEdit->setFont(
            fontManager.getFont(singletons::FontManager::Type::Medium, this->getScale()));
    }));

    // open emote popup
    QObject::connect(this->ui.emoteButton, &RippleEffectLabel::clicked, [this] {
        if (!this->emotePopup) {
            this->emotePopup = std::make_unique<EmotePopup>(this->themeManager);
            this->emotePopup->linkClicked.connect([this](const messages::Link &link) {
                if (link.getType() == messages::Link::InsertText) {
                    this->insertText(link.getValue() + " ");
                }
            });
        }

        this->emotePopup->resize((int)(300 * this->emotePopup->getScale()),
                                 (int)(500 * this->emotePopup->getScale()));
        this->emotePopup->loadChannel(this->chatWidget->getChannel());
        this->emotePopup->show();
    });

    // clear channelview selection when selecting in the input
    QObject::connect(this->ui.textEdit, &QTextEdit::copyAvailable, [this](bool available) {
        if (available) {
            this->chatWidget->view.clearSelection();
        }
    });

    // textEditLength visibility
    singletons::SettingManager::getInstance().showMessageLength.connect(
        [this](const bool &value, auto) { this->ui.textEditLength->setHidden(!value); },
        this->managedConnections);
}

void SplitInput::scaleChangedEvent(float scale)
{
    // update the icon size of the emote button
    QString text = "";
    text.replace("xD", QString::number((int)12 * scale));

    this->ui.emoteButton->getLabel().setText(text);
    this->ui.emoteButton->setFixedHeight((int)18 * scale);

    // set maximum height
    this->setMaximumHeight((int)(150 * this->getScale()));

    this->themeRefreshEvent();
}

void SplitInput::themeRefreshEvent()
{
    QPalette palette;

    palette.setColor(QPalette::Foreground, this->themeManager.splits.input.text);

    this->ui.textEditLength->setPalette(palette);

    this->ui.textEdit->setStyleSheet(this->themeManager.splits.input.styleSheet);

    this->ui.hbox->setMargin((this->themeManager.isLightTheme() ? 4 : 2) * this->getScale());
}

void SplitInput::installKeyPressedEvent()
{
    this->ui.textEdit->keyPressed.connect([this](QKeyEvent *event) {
        if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
            auto c = this->chatWidget->getChannel();
            if (c == nullptr) {
                return;
            }
            QString message = ui.textEdit->toPlainText();

            QString sendMessage =
                singletons::CommandManager::getInstance().execCommand(message, c, false);
            sendMessage = sendMessage.replace('\n', ' ');

            c->sendMessage(sendMessage);
            this->prevMsg.append(message);

            event->accept();
            if (!(event->modifiers() == Qt::ControlModifier)) {
                this->ui.textEdit->setText(QString());
                this->prevIndex = 0;
            } else if (this->ui.textEdit->toPlainText() ==
                       this->prevMsg.at(this->prevMsg.size() - 1)) {
                this->prevMsg.removeLast();
            }
            this->prevIndex = this->prevMsg.size();
        } else if (event->key() == Qt::Key_Up) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX;
                int reqY = page->lastRequestedY[reqX] - 1;

                qDebug() << "Alt+Down to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            } else {
                if (this->prevMsg.size() && this->prevIndex) {
                    this->prevIndex--;
                    this->ui.textEdit->setText(this->prevMsg.at(this->prevIndex));
                }
            }
        } else if (event->key() == Qt::Key_Down) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX;
                int reqY = page->lastRequestedY[reqX] + 1;

                qDebug() << "Alt+Down to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            } else {
                if (this->prevIndex != (this->prevMsg.size() - 1) &&
                    this->prevIndex != this->prevMsg.size()) {
                    this->prevIndex++;
                    this->ui.textEdit->setText(this->prevMsg.at(this->prevIndex));
                } else {
                    this->prevIndex = this->prevMsg.size();
                    this->ui.textEdit->setText(QString());
                }
            }
        } else if (event->key() == Qt::Key_Left) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX - 1;
                int reqY = page->lastRequestedY[reqX];

                qDebug() << "Alt+Left to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            }
        } else if (event->key() == Qt::Key_Right) {
            if (event->modifiers() == Qt::AltModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                int reqX = page->currentX + 1;
                int reqY = page->lastRequestedY[reqX];

                qDebug() << "Alt+Right to" << reqX << "/" << reqY;

                page->requestFocus(reqX, reqY);
            }
        } else if (event->key() == Qt::Key_Tab) {
            if (event->modifiers() == Qt::ControlModifier) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                Notebook *notebook = static_cast<Notebook *>(page->parentWidget());

                notebook->nextTab();
            }
        } else if (event->key() == Qt::Key_Backtab) {
            if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) {
                SplitContainer *page =
                    static_cast<SplitContainer *>(this->chatWidget->parentWidget());

                Notebook *notebook = static_cast<Notebook *>(page->parentWidget());

                notebook->previousTab();
            }
        } else if (event->key() == Qt::Key_C && event->modifiers() == Qt::ControlModifier) {
            if (this->chatWidget->view.hasSelection()) {
                this->chatWidget->doCopy();
                event->accept();
            }
        }
    });
}

void SplitInput::clearSelection()
{
    QTextCursor c = this->ui.textEdit->textCursor();

    c.setPosition(c.position());
    c.setPosition(c.position(), QTextCursor::KeepAnchor);

    this->ui.textEdit->setTextCursor(c);
}

QString SplitInput::getInputText() const
{
    return this->ui.textEdit->toPlainText();
}

void SplitInput::insertText(const QString &text)
{
    this->ui.textEdit->insertPlainText(text);
}

void SplitInput::editTextChanged()
{
    // set textLengthLabel value
    QString text = this->ui.textEdit->toPlainText();

    this->textChanged.invoke(text);

    text = text.trimmed();
    static QRegularExpression spaceRegex("\\s\\s+");
    text = text.replace(spaceRegex, " ");

    text = singletons::CommandManager::getInstance().execCommand(
        text, this->chatWidget->getChannel(), true);

    QString labelText;

    if (text.length() == 0) {
        labelText = "";
    } else {
        labelText = QString::number(text.length());
    }

    this->ui.textEditLength->setText(labelText);
}

void SplitInput::paintEvent(QPaintEvent *)
{
    QPainter painter(this);

    painter.fillRect(this->rect(), this->themeManager.splits.input.background);

    QPen pen(this->themeManager.splits.input.border);
    if (this->themeManager.isLightTheme()) {
        pen.setWidth((int)(6 * this->getScale()));
    }
    painter.setPen(pen);
    painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
}

void SplitInput::resizeEvent(QResizeEvent *)
{
    if (this->height() == this->maximumHeight()) {
        this->ui.textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    } else {
        this->ui.textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    }
}

void SplitInput::mousePressEvent(QMouseEvent *)
{
    this->chatWidget->giveFocus(Qt::MouseFocusReason);
}

}  // namespace widgets
}  // namespace chatterino
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

/**
 * @author Matthew Hoyt (mhoyt@ca.ibm.com)
 */

#if !defined(XALANDEQUE_HEADER_GUARD_1357924680)
#define XALANDEQUE_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>

#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/XalanMemoryManagement.hpp>

XALAN_CPP_NAMESPACE_BEGIN

template <class Value>
struct XalanDequeIteratorTraits
{
    typedef Value           value_type;
    typedef Value&          reference;
    typedef Value*          pointer;
    typedef const Value&    const_reference;
};

template <class Value>
struct XalanDequeConstIteratorTraits
{
    typedef Value           value_type;
    typedef const Value&    reference;
    typedef const Value*    pointer;
    typedef const Value&    const_reference;
};

template <class XalanDequeTraits, class XalanDeque>
struct  XalanDequeIterator
{
    typedef size_t  size_type;
    typedef typename XalanDequeTraits::value_type       value_type;
    typedef typename XalanDequeTraits::reference        reference;
    typedef typename XalanDequeTraits::pointer          pointer;
    typedef typename XalanDequeTraits::const_reference  const_reference;
    typedef ptrdiff_t                                   difference_type;

    typedef XalanDequeIterator<XalanDequeIteratorTraits<value_type>, XalanDeque> Iterator;

    typedef XALAN_STD_QUALIFIER random_access_iterator_tag iterator_category;

    XalanDequeIterator(XalanDeque*  deque,
                       size_type    pos) :
        m_deque(deque),
        m_pos(pos)
    {
    }

    XalanDequeIterator(const Iterator & iterator) :
        m_deque(iterator.m_deque),
        m_pos(iterator.m_pos)
    {
    }

    XalanDequeIterator& operator=(const Iterator & iterator)
    {
        m_deque = iterator.m_deque;
        m_pos = iterator.m_pos;
        return *this;
    }

    XalanDequeIterator& operator++()
    {
        ++m_pos;
        return *this;
    }

    XalanDequeIterator operator++(int)
    {
        XalanDequeIterator temp = *this;
        ++m_pos;
        return temp;
    }

    XalanDequeIterator& operator--()
    {
        --m_pos;
        return *this;
    }

    pointer operator->()
    {
        return &(*m_deque[m_pos]);
    }

    reference operator*()
    {
        return (*m_deque)[m_pos];
    }

    const_reference operator*() const
    {
        return (*m_deque)[m_pos];
    }

    XalanDequeIterator operator+(difference_type difference) const
    {
        return XalanDequeIterator(m_deque, m_pos + difference);
    }

    XalanDequeIterator operator-(difference_type difference) const
    {
        return XalanDequeIterator(m_deque, m_pos - difference);
    }

    difference_type operator-(const XalanDequeIterator &theRhs) const
    {
        return m_pos - theRhs.m_pos;
    }

    bool operator==(const XalanDequeIterator & theRhs) const
    {
        return (theRhs.m_deque == m_deque)
            &&  theRhs.m_pos == m_pos;
    }

    bool operator!=(const XalanDequeIterator & theRhs) const
    {
        return !(theRhs == *this);
    }

    bool operator<(const XalanDequeIterator & theRhs) const
    {
        return m_pos < theRhs.m_pos;
    }

    XalanDeque* m_deque;
    size_type   m_pos;
};

/**
 * Xalan implementation of deque
 */
template <class Type, class ConstructionTraits = MemoryManagedConstructionTraits<Type> >
class XalanDeque
{
public:

    typedef size_t  size_type;

    typedef Type            value_type;
    typedef Type&           reference;
    typedef const Type&     const_reference;

    typedef XalanVector<Type, ConstructionTraits>       BlockType;

    typedef XalanVector<BlockType*> BlockIndexType;

    typedef XalanDeque<Type, ConstructionTraits>                            ThisType;
    typedef XalanDequeIterator<XalanDequeIteratorTraits<value_type>, ThisType>      iterator;
    typedef XalanDequeIterator<XalanDequeConstIteratorTraits<value_type>, ThisType>     const_iterator;

#if defined(XALAN_HAS_STD_ITERATORS)
    typedef XALAN_STD_QUALIFIER reverse_iterator<iterator>          reverse_iterator_;
    typedef XALAN_STD_QUALIFIER reverse_iterator<const_iterator>    const_reverse_iterator_;
#elif defined(XALAN_RW_NO_CLASS_PARTIAL_SPEC)
    typedef XALAN_STD_QUALIFIER reverse_iterator<
        iterator,
        XALAN_STD_QUALIFIER random_access_iterator_tag,
        value_type> reverse_iterator_;
    typedef XALAN_STD_QUALIFIER reverse_iterator<
        const_iterator,
        XALAN_STD_QUALIFIER random_access_iterator_tag,
        const value_type> const_reverse_iterator_;
#else
    typedef XALAN_STD_QUALIFIER reverse_iterator<iterator, value_type>                          reverse_iterator_;
    typedef XALAN_STD_QUALIFIER reverse_iterator<const_iterator, value_type, const_reference>   const_reverse_iterator_;
#endif

    typedef reverse_iterator_           reverse_iterator;
    typedef const_reverse_iterator_     const_reverse_iterator;

    typedef typename ConstructionTraits::Constructor    Constructor;
    typedef typename Constructor::ConstructableType     ConstructibleType;

    XalanDeque(
            MemoryManagerType& memoryManager,
            size_type initialSize = 0,
            size_type blockSize = 10) :
        m_memoryManager(&memoryManager),
        m_blockSize(blockSize),
        m_blockIndex(memoryManager,
                    initialSize / blockSize + (initialSize % blockSize == 0 ? 0 : 1)),
        m_freeBlockVector(memoryManager)
    {
        typename Constructor::ConstructableType  defaultValue(*m_memoryManager);

        XALAN_STD_QUALIFIER fill_n(XALAN_STD_QUALIFIER back_inserter(*this), initialSize, defaultValue.value);
    }

    XalanDeque(const XalanDeque& theRhs, MemoryManagerType& memoryManager) :
        m_memoryManager(&memoryManager),
        m_blockSize(theRhs.m_blockSize),
        m_blockIndex(*theRhs.m_memoryManager,
                    theRhs.size() / theRhs.m_blockSize + (theRhs.size() % theRhs.m_blockSize == 0 ? 0 : 1)),
        m_freeBlockVector(memoryManager)
    {
        XALAN_STD_QUALIFIER copy(theRhs.begin(), theRhs.end(), XALAN_STD_QUALIFIER back_inserter(*this));
    }

   static XalanDeque*
   create(
            MemoryManagerType&  theManager,
            size_type initialSize = 0,
            size_type blockSize = 10)
    {
        typedef XalanDeque ThisType;

        XalanMemMgrAutoPtr<ThisType, false> theGuard( theManager , (ThisType*)theManager.allocate(sizeof(ThisType)));

        ThisType* theResult = theGuard.get();

        new (theResult) ThisType(theManager, initialSize, blockSize);

        theGuard.release();

        return theResult;
    }

    ~XalanDeque()
    {
        destroyBlockList(m_freeBlockVector);

        destroyBlockList(m_blockIndex);
    }

    iterator begin()
    {
        return iterator(this, 0);
    }

    const_iterator begin() const
    {
        return const_iterator(const_cast<XalanDeque*>(this), 0);
    }

    iterator end()
    {
        return iterator(this, size());
    }

    const_iterator end() const
    {
         return const_iterator(const_cast<XalanDeque*>(this), size());
    }

    const_reverse_iterator rbegin() const
    {
        return const_reverse_iterator(end());
    }

    const_reverse_iterator rend() const
    {
        return const_reverse_iterator(begin());
    }

    bool empty() const
    {
        return m_blockIndex.empty();
    }

    size_type size() const
    {
       if (m_blockIndex.empty())
       {
           return 0;
       }
       else
       {
           return (m_blockIndex.size() - 1) * m_blockSize
               +  m_blockIndex.back()->size();
       }
    }

    value_type& back()
    {
        return m_blockIndex.back()->back();
    }

    value_type& operator[](size_type index)
    {
        BlockType & block = *(m_blockIndex[index / m_blockSize]);
        return block[index % m_blockSize];
    }

    const value_type& operator[](size_type index) const
    {
        BlockType & block = *(m_blockIndex[index / m_blockSize]);
        return block[index % m_blockSize];
    }

    void clear()
    {
        typename BlockIndexType::iterator iter = m_blockIndex.begin();

        m_freeBlockVector.reserve(m_freeBlockVector.size() + m_blockIndex.size());

        while (iter != m_blockIndex.end())
        {
            (*iter)->clear();
            m_freeBlockVector.push_back(*iter);
            ++iter;
        }

        m_blockIndex.clear();
    }

    void push_back(const value_type & value)
    {
        if (m_blockIndex.empty() ||
            m_blockIndex.back()->size() >= m_blockSize)
        {
            m_blockIndex.push_back(getNewBlock());
        }

        m_blockIndex.back()->push_back(value);
    }

    void pop_back()
    {
        BlockType & lastBlock = *(m_blockIndex.back());
        lastBlock.pop_back();
        if (lastBlock.empty())
        {
            m_freeBlockVector.push_back(&lastBlock);
            m_blockIndex.pop_back();
        }
    }

    void resize(size_type newSize)
    {
        typename Constructor::ConstructableType  defaultValue(*m_memoryManager);

        if (newSize > size())
        {
            for (size_type i = 0; i < newSize - size(); ++i)
            {
                push_back(defaultValue.value);
            }
        }
        else
        {
            for (size_type i = 0; i < size() - newSize; ++i)
            {
                pop_back();
            }
        }
    }

    void swap(XalanDeque& theRhs)
    {
        MemoryManagerType* tempMemoryManager = m_memoryManager;
        m_memoryManager = theRhs.m_memoryManager;
        theRhs.m_memoryManager = tempMemoryManager;

        theRhs.m_blockIndex.swap(m_blockIndex);
        theRhs.m_freeBlockVector.swap(m_freeBlockVector);
    }

    XalanDeque & operator=(const XalanDeque & theRhs)
    {
        clear();
        XALAN_STD_QUALIFIER copy(theRhs.begin(), theRhs.end(), XALAN_STD_QUALIFIER back_inserter(*this));
        return *this;
    }

    MemoryManagerType&
    getMemoryManager()
    {
        assert (m_memoryManager != 0);

        return *m_memoryManager;
    }

protected:

    BlockType* getNewBlock()
    {
        BlockType * newBlock;

        if (m_freeBlockVector.empty())
        {
            newBlock = allocate(1);
            new (&*newBlock) BlockType(*m_memoryManager, m_blockSize);
        }
        else
        {
            newBlock = m_freeBlockVector.back();
            m_freeBlockVector.pop_back();
        }

        assert (newBlock != 0);

        return newBlock;
    }

    BlockType*
    allocate(size_type  size)
    {
        const size_type     theBytesNeeded = size * sizeof(BlockType);

        BlockType* pointer = (BlockType*)m_memoryManager->allocate(theBytesNeeded);

        assert(pointer != 0);

        return pointer;
    }

    void
    destroyBlockList(BlockIndexType&    theBlockIndex)
    {
        typename BlockIndexType::iterator iter =
            theBlockIndex.begin();

        while (iter != theBlockIndex.end())
        {
            XalanDestroy(*m_memoryManager, *(*iter));

            ++iter;
        }
    }

    void
    deallocate(BlockType*  pointer)
    {
        m_memoryManager->deallocate(pointer);
    }

    MemoryManagerType*  m_memoryManager;
    const size_type     m_blockSize;

    BlockIndexType     m_blockIndex;
    BlockIndexType     m_freeBlockVector;

private:

    // These are not implemented
    XalanDeque();

    XalanDeque(const XalanDeque&);
};

XALAN_CPP_NAMESPACE_END

#endif  // XALANDEQUE_HEADER_GUARD_1357924680

<commit_msg>Major error reporting cleanup.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

/**
 * @author Matthew Hoyt (mhoyt@ca.ibm.com)
 */

#if !defined(XALANDEQUE_HEADER_GUARD_1357924680)
#define XALANDEQUE_HEADER_GUARD_1357924680

// Base include file.  Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>

#include <xalanc/Include/XalanVector.hpp>
#include <xalanc/Include/XalanMemoryManagement.hpp>

XALAN_CPP_NAMESPACE_BEGIN

template <class Value>
struct XalanDequeIteratorTraits
{
    typedef Value           value_type;
    typedef Value&          reference;
    typedef Value*          pointer;
    typedef const Value&    const_reference;
};

template <class Value>
struct XalanDequeConstIteratorTraits
{
    typedef Value           value_type;
    typedef const Value&    reference;
    typedef const Value*    pointer;
    typedef const Value&    const_reference;
};

template <class XalanDequeTraits, class XalanDeque>
struct  XalanDequeIterator
{
    typedef size_t  size_type;
    typedef typename XalanDequeTraits::value_type       value_type;
    typedef typename XalanDequeTraits::reference        reference;
    typedef typename XalanDequeTraits::pointer          pointer;
    typedef typename XalanDequeTraits::const_reference  const_reference;
    typedef ptrdiff_t                                   difference_type;

    typedef XalanDequeIterator<XalanDequeIteratorTraits<value_type>, XalanDeque> Iterator;

    typedef XALAN_STD_QUALIFIER random_access_iterator_tag iterator_category;

    XalanDequeIterator(XalanDeque*  deque,
                       size_type    pos) :
        m_deque(deque),
        m_pos(pos)
    {
    }

    XalanDequeIterator(const Iterator & iterator) :
        m_deque(iterator.m_deque),
        m_pos(iterator.m_pos)
    {
    }

    XalanDequeIterator& operator=(const Iterator & iterator)
    {
        m_deque = iterator.m_deque;
        m_pos = iterator.m_pos;
        return *this;
    }

    XalanDequeIterator& operator++()
    {
        ++m_pos;
        return *this;
    }

    XalanDequeIterator operator++(int)
    {
        XalanDequeIterator temp = *this;
        ++m_pos;
        return temp;
    }

    XalanDequeIterator& operator--()
    {
        --m_pos;
        return *this;
    }

    pointer operator->()
    {
        return &(*m_deque[m_pos]);
    }

    reference operator*()
    {
        return (*m_deque)[m_pos];
    }

    const_reference operator*() const
    {
        return (*m_deque)[m_pos];
    }

    XalanDequeIterator operator+(difference_type difference) const
    {
        return XalanDequeIterator(m_deque, m_pos + difference);
    }

    XalanDequeIterator operator-(difference_type difference) const
    {
        return XalanDequeIterator(m_deque, m_pos - difference);
    }

    difference_type operator-(const XalanDequeIterator &theRhs) const
    {
        return m_pos - theRhs.m_pos;
    }

    bool operator==(const XalanDequeIterator & theRhs) const
    {
        return (theRhs.m_deque == m_deque)
            &&  theRhs.m_pos == m_pos;
    }

    bool operator!=(const XalanDequeIterator & theRhs) const
    {
        return !(theRhs == *this);
    }

    bool operator<(const XalanDequeIterator & theRhs) const
    {
        return m_pos < theRhs.m_pos;
    }

    XalanDeque* m_deque;
    size_type   m_pos;
};

/**
 * Xalan implementation of deque
 */
template <class Type, class ConstructionTraits = MemoryManagedConstructionTraits<Type> >
class XalanDeque
{
public:

    typedef size_t  size_type;

    typedef Type            value_type;
    typedef Type&           reference;
    typedef const Type&     const_reference;

    typedef XalanVector<Type, ConstructionTraits>       BlockType;

    typedef XalanVector<BlockType*> BlockIndexType;

    typedef XalanDeque<Type, ConstructionTraits>                            ThisType;
    typedef XalanDequeIterator<XalanDequeIteratorTraits<value_type>, ThisType>      iterator;
    typedef XalanDequeIterator<XalanDequeConstIteratorTraits<value_type>, ThisType>     const_iterator;

#if defined(XALAN_HAS_STD_ITERATORS)
    typedef XALAN_STD_QUALIFIER reverse_iterator<iterator>          reverse_iterator_;
    typedef XALAN_STD_QUALIFIER reverse_iterator<const_iterator>    const_reverse_iterator_;
#elif defined(XALAN_RW_NO_CLASS_PARTIAL_SPEC)
    typedef XALAN_STD_QUALIFIER reverse_iterator<
        iterator,
        XALAN_STD_QUALIFIER random_access_iterator_tag,
        value_type> reverse_iterator_;
    typedef XALAN_STD_QUALIFIER reverse_iterator<
        const_iterator,
        XALAN_STD_QUALIFIER random_access_iterator_tag,
        const value_type> const_reverse_iterator_;
#else
    typedef XALAN_STD_QUALIFIER reverse_iterator<iterator, value_type>                          reverse_iterator_;
    typedef XALAN_STD_QUALIFIER reverse_iterator<const_iterator, value_type, const_reference>   const_reverse_iterator_;
#endif

    typedef reverse_iterator_           reverse_iterator;
    typedef const_reverse_iterator_     const_reverse_iterator;

    typedef typename ConstructionTraits::Constructor    Constructor;
    typedef typename Constructor::ConstructableType     ConstructibleType;

    XalanDeque(
            MemoryManagerType& memoryManager,
            size_type initialSize = 0,
            size_type blockSize = 10) :
        m_memoryManager(&memoryManager),
        m_blockSize(blockSize),
        m_blockIndex(memoryManager,
                    initialSize / blockSize + (initialSize % blockSize == 0 ? 0 : 1)),
        m_freeBlockVector(memoryManager)
    {
        typename Constructor::ConstructableType  defaultValue(*m_memoryManager);

        XALAN_STD_QUALIFIER fill_n(XALAN_STD_QUALIFIER back_inserter(*this), initialSize, defaultValue.value);
    }

    XalanDeque(const XalanDeque& theRhs, MemoryManagerType& memoryManager) :
        m_memoryManager(&memoryManager),
        m_blockSize(theRhs.m_blockSize),
        m_blockIndex(*theRhs.m_memoryManager,
                    theRhs.size() / theRhs.m_blockSize + (theRhs.size() % theRhs.m_blockSize == 0 ? 0 : 1)),
        m_freeBlockVector(memoryManager)
    {
        XALAN_STD_QUALIFIER copy(theRhs.begin(), theRhs.end(), XALAN_STD_QUALIFIER back_inserter(*this));
    }

   static XalanDeque*
   create(
            MemoryManager&  theManager,
            size_type       initialSize = 0,
            size_type       blockSize = 10)
    {
        typedef XalanDeque ThisType;

        XalanAllocationGuard    theGuard(theManager, theManager.allocate(sizeof(ThisType)));

        ThisType* const     theResult =
            new (theGuard.get()) ThisType(theManager, initialSize, blockSize);

        theGuard.release();

        return theResult;
    }

    ~XalanDeque()
    {
        destroyBlockList(m_freeBlockVector);

        destroyBlockList(m_blockIndex);
    }

    iterator begin()
    {
        return iterator(this, 0);
    }

    const_iterator begin() const
    {
        return const_iterator(const_cast<XalanDeque*>(this), 0);
    }

    iterator end()
    {
        return iterator(this, size());
    }

    const_iterator end() const
    {
         return const_iterator(const_cast<XalanDeque*>(this), size());
    }

    const_reverse_iterator rbegin() const
    {
        return const_reverse_iterator(end());
    }

    const_reverse_iterator rend() const
    {
        return const_reverse_iterator(begin());
    }

    bool empty() const
    {
        return m_blockIndex.empty();
    }

    size_type size() const
    {
       if (m_blockIndex.empty())
       {
           return 0;
       }
       else
       {
           return (m_blockIndex.size() - 1) * m_blockSize
               +  m_blockIndex.back()->size();
       }
    }

    value_type& back()
    {
        return m_blockIndex.back()->back();
    }

    value_type& operator[](size_type index)
    {
        BlockType & block = *(m_blockIndex[index / m_blockSize]);
        return block[index % m_blockSize];
    }

    const value_type& operator[](size_type index) const
    {
        BlockType & block = *(m_blockIndex[index / m_blockSize]);
        return block[index % m_blockSize];
    }

    void clear()
    {
        typename BlockIndexType::iterator iter = m_blockIndex.begin();

        m_freeBlockVector.reserve(m_freeBlockVector.size() + m_blockIndex.size());

        while (iter != m_blockIndex.end())
        {
            (*iter)->clear();
            m_freeBlockVector.push_back(*iter);
            ++iter;
        }

        m_blockIndex.clear();
    }

    void push_back(const value_type & value)
    {
        if (m_blockIndex.empty() ||
            m_blockIndex.back()->size() >= m_blockSize)
        {
            m_blockIndex.push_back(getNewBlock());
        }

        m_blockIndex.back()->push_back(value);
    }

    void pop_back()
    {
        BlockType & lastBlock = *(m_blockIndex.back());
        lastBlock.pop_back();
        if (lastBlock.empty())
        {
            m_freeBlockVector.push_back(&lastBlock);
            m_blockIndex.pop_back();
        }
    }

    void resize(size_type newSize)
    {
        typename Constructor::ConstructableType  defaultValue(*m_memoryManager);

        if (newSize > size())
        {
            for (size_type i = 0; i < newSize - size(); ++i)
            {
                push_back(defaultValue.value);
            }
        }
        else
        {
            for (size_type i = 0; i < size() - newSize; ++i)
            {
                pop_back();
            }
        }
    }

    void swap(XalanDeque& theRhs)
    {
        MemoryManagerType* tempMemoryManager = m_memoryManager;
        m_memoryManager = theRhs.m_memoryManager;
        theRhs.m_memoryManager = tempMemoryManager;

        theRhs.m_blockIndex.swap(m_blockIndex);
        theRhs.m_freeBlockVector.swap(m_freeBlockVector);
    }

    XalanDeque & operator=(const XalanDeque & theRhs)
    {
        clear();
        XALAN_STD_QUALIFIER copy(theRhs.begin(), theRhs.end(), XALAN_STD_QUALIFIER back_inserter(*this));
        return *this;
    }

    MemoryManagerType&
    getMemoryManager()
    {
        assert (m_memoryManager != 0);

        return *m_memoryManager;
    }

protected:

    BlockType* getNewBlock()
    {
        BlockType * newBlock;

        if (m_freeBlockVector.empty())
        {
            newBlock = allocate(1);
            new (&*newBlock) BlockType(*m_memoryManager, m_blockSize);
        }
        else
        {
            newBlock = m_freeBlockVector.back();
            m_freeBlockVector.pop_back();
        }

        assert (newBlock != 0);

        return newBlock;
    }

    BlockType*
    allocate(size_type  size)
    {
        const size_type     theBytesNeeded = size * sizeof(BlockType);

        BlockType* pointer = (BlockType*)m_memoryManager->allocate(theBytesNeeded);

        assert(pointer != 0);

        return pointer;
    }

    void
    destroyBlockList(BlockIndexType&    theBlockIndex)
    {
        typename BlockIndexType::iterator iter =
            theBlockIndex.begin();

        while (iter != theBlockIndex.end())
        {
            XalanDestroy(*m_memoryManager, *(*iter));

            ++iter;
        }
    }

    void
    deallocate(BlockType*  pointer)
    {
        m_memoryManager->deallocate(pointer);
    }

    MemoryManagerType*  m_memoryManager;
    const size_type     m_blockSize;

    BlockIndexType     m_blockIndex;
    BlockIndexType     m_freeBlockVector;

private:

    // These are not implemented
    XalanDeque();

    XalanDeque(const XalanDeque&);
};

XALAN_CPP_NAMESPACE_END

#endif  // XALANDEQUE_HEADER_GUARD_1357924680

<|endoftext|>