<commit_before>#include "query.h"

using namespace orm;

Query::Query(const Query &) : m_queryType(QueryInvalid){}
Query &Query::operator=(const Query &){}

Query::Query(const QString &entity, QueryTypes type, const QString &connection) :
    m_entity(entity),
    m_queryType(type),
    m_currentConnectionName(connection),
    m_isDistinct(false),
    m_limitCount(0),
    m_limitStart(0)
{
}

Query::~Query(){}

const QSqlDatabase &Query::db() const
{
    static QSqlDatabase db;

    if (!db.isOpen()) {
        if (db.contains(m_currentConnectionName)) {
            db = QSqlDatabase::database(m_currentConnectionName);
        } else {
            db = QSqlDatabase::database();
        }
    }

    Q_ASSERT_X(db.isValid(), "ORM", "database connection not valid");
    Q_ASSERT_X(db.driver()->hasFeature(QSqlDriver::LastInsertId), "ORM", "database driver does not support last insert ID returning");
    Q_ASSERT_X(db.driver()->hasFeature(QSqlDriver::PreparedQueries), "ORM", "database driver does not support prepared queries");

    return db;
}

Query Query::select(const QString &entity, const QString &connection)
{
    return Query(entity, QuerySelect, connection);
}

Query Query::insert(const QString &entity, const QString &connection)
{
    return Query(entity, QueryInsert, connection);
}

Query Query::update(const QString &entity, const QString &connection)
{
    return Query(entity, QueryUpdate, connection);
}

Query Query::remove(const QString &entity, const QString &connection)
{
    return Query(entity, QueryRemove, connection);
}

void Query::createSelect(QSqlQuery &qr)
{
    QStringList sql;

    sql << "SELECT";

    if (m_isDistinct) {
        sql << "DISTINCT";
    }

    if (m_fields.count() == 0) {
        m_fields += entityFields(m_entity);
        for (int i = 0; i < m_joinEntities.count(); i++) {
            m_fields += entityFields(m_joinEntities.at(i));
        }
    }
    sql << m_fields.join(',');

    sql << "FROM" << m_entity;

    if (m_joinSql.count() > 0) {
        sql += m_joinSql;
    }

    if (!m_whereItems.isEmpty()) {
        sql << "WHERE";
        sql << m_whereItems;
    }

    if (!m_order.isEmpty()) {
        sql << "ORDER BY" << m_order;
    }

    if (m_limitCount != 0) {
        sql << "LIMIT" << QString("%1, %2").arg(m_limitCount, m_limitStart);
    }

    if (!m_group.isEmpty()) {
        sql << "GROUP BY" << m_group;
    }

    if (qr.prepare(sql.join(' '))) {
        for (int i = 0; i < m_whereBounds.count(); i++) {
            qr.addBindValue(m_whereBounds.at(i));
        }
    }
}

void Query::createInsert(QSqlQuery &qr)
{
    QStringList sql;
    sql << QString("INSERT INTO %1").arg(m_entity);

    QStringList fields, placeholders;
    for (int i=0; i < m_values.count(); i++) {
        if (m_values.field(i).value().isValid()) {
            fields << m_values.fieldName(i);
            placeholders << "?";
        }
    }

    sql << QString("(%1)").arg(fields.join(','))
        << QString("VALUES (%1)").arg(placeholders.join(','));

    if (qr.prepare(sql.join(' '))) {
        for (int i=0; i < fields.size(); i++) {
            int ix = m_values.indexOf(fields.at(i));
            qr.addBindValue(m_values.field(ix).value());
        }
    }
}

void Query::createUpdate(QSqlQuery &qr)
{
    QSqlIndex pi = db().primaryIndex(m_entity);

    QStringList sql;
    sql << QString("UPDATE %1").arg(m_entity)
        << "SET";

    QStringList fields,fields_sql;
    for (int i=0; i < m_values.count(); i++) {
        if (pi.contains(m_values.field(i).name())) continue;
        if (m_values.field(i).value().isValid()) {
            fields << m_values.field(i).name();
            fields_sql << QString("%1 = ?").arg(m_values.field(i).name());
        }
    }
    sql << fields_sql.join(',');

    if (!m_whereItems.isEmpty()) {
        sql << "WHERE";
        sql << m_whereItems;
    }

    if (qr.prepare(sql.join(' '))) {
        for (int i = 0; i < fields.size(); i++) {
            qr.addBindValue(m_values.field(fields.at(i)).value());
        }
        for (int i = 0; i < m_whereBounds.size(); i++) {
            qr.addBindValue(m_whereBounds.at(i));
        }
    }
}

void Query::createRemove(QSqlQuery &qr)
{
    QStringList sql;
    sql << QString("DELETE FROM %1").arg(m_entity);

    if (!m_whereItems.isEmpty()) {
        sql << "WHERE";
        sql << m_whereItems;
    }

    if (qr.prepare(sql.join(' '))) {
        for (int i = 0; i < m_whereBounds.size(); i++) {
            qr.addBindValue(m_whereBounds.at(i));
        }
    }
}

QString Query::escapeTableName(const QString &table)
{
    return db().driver()->escapeIdentifier(table, QSqlDriver::TableName);
}

QString Query::escapeFieldName(const QString &field)
{
    return db().driver()->escapeIdentifier(field, QSqlDriver::FieldName);
}

QStringList Query::entityFields(const QString &entity)
{
    QStringList fields_list;

    QSqlRecord rec = db().record(entity);
    for (int i = 0; i < rec.count(); i++) {
        QString pk_name = db().primaryIndex(entity).field(0).name();
        if (pk_name == rec.field(i).name()) {
            if (entity == m_entity) {
                fields_list << QString("%1.%2 AS %2").arg(escapeTableName(entity)).arg(escapeFieldName(pk_name));
            }
            continue;
        }
        QString postfix;
        QString full_name = QString("%1.%2").arg(entity).arg(rec.fieldName(i));
        if (entity == m_entity) {
            postfix = escapeFieldName(rec.fieldName(i));
        } else {
            // TODO hove to work this with driver side escaping
            postfix = QString("\"%1\"").arg(full_name);
        }
        fields_list << QString("%1 AS %2").arg(escapeTableName(full_name)).arg(postfix);
    }

    return fields_list;
}

QSqlQuery Query::make()
{
    QSqlQuery qr;

    switch (m_queryType) {
        case QuerySelect:
            createSelect(qr);
            break;
        case QueryInsert:
            createInsert(qr);
            break;
        case QueryUpdate:
            createUpdate(qr);
            break;
        case QueryRemove:
            createRemove(qr);
            break;
        default:
            break;
    }

    return qr;
}

Query &Query::where(const QString &sql, QVariantList binds)
{
    m_whereItems = sql;
    m_whereBounds = binds;
    return *this;
}

Query &Query::where(const QString &sql, const QVariant &bind)
{
    return where(sql, QVariantList() << bind);
}

Query &Query::where(const QString &sql)
{
    return where(sql, QVariantList());
}

Query &Query::distinct()
{
    m_isDistinct = true;
    return *this;
}

Query &Query::fields(const QString &fields_sql)
{
    m_fields << fields_sql;
    return *this;
}

Query &Query::fields(const QStringList &fields_list)
{
    return fields(fields_list.join(','));
}

Query &Query::fieldsFrom(const QString &entity)
{
    return fields(entityFields(entity));
}

Query &Query::order(const QString &fields_sql)
{
    m_order = fields_sql;
    return *this;
}

Query &Query::limit(int limit_count, int limit_start)
{
    m_limitCount = limit_count;
    m_limitStart = limit_start;
    return *this;
}

Query &Query::join(const QString &ent, const QString &fk, Query::JoinTypes join_type)
{
    QString join_type_str;
    switch (join_type) {
        case JoinLeft:
            join_type_str = "LEFT JOIN";
            break;
        case JoinRight:
            join_type_str = "RIGHT JOIN";
            break;
        case JoinInner:
            join_type_str = "INNER JOIN";
            break;
        default:
            join_type_str = "JOIN";
            break;
    }

    m_joinEntities << ent;
    m_joinSql << QString ("%1 %3 ON %2.%4 = %3.%5").arg(join_type_str)
                                                   .arg(m_entity)
                                                   .arg(ent)
                                                   .arg(fk)
                                                   .arg(db().primaryIndex(ent).field(0).name());

    return *this;
}

Query &Query::join(const QString &join_sql)
{
    m_joinSql << join_sql;
    return *this;
}

Query &Query::group(const QString &fields_sql)
{
    m_group = fields_sql;
    return *this;
}

Query &Query::values(const QSqlRecord &rec)
{
    m_values = rec;
    return *this;
}

Query &Query::values(const QMap<QString, QVariant> &values_map)
{
    QSqlRecord rec;
    QMapIterator<QString, QVariant> i(values_map);
    while (i.hasNext()) {
        i.next();
        QSqlField fld(i.key());
        fld.setValue(i.value());
        rec.append(fld);
    }
    return values(rec);
}

Query &Query::values(const QSqlField &field)
{
    QSqlRecord rec;
    rec.append(field);
    return values(rec);
}

Query &Query::values(const QString &name, const QVariant &value)
{
    QSqlField fld(name);
    fld.setValue(value);
    return values(fld);
}
<commit_msg>fix: in query builder by default all unsetted (null) fields about to be removed<commit_after>#include "query.h"

using namespace orm;

Query::Query(const Query &) : m_queryType(QueryInvalid){}
Query &Query::operator=(const Query &){}

Query::Query(const QString &entity, QueryTypes type, const QString &connection) :
    m_entity(entity),
    m_queryType(type),
    m_currentConnectionName(connection),
    m_isDistinct(false),
    m_limitCount(0),
    m_limitStart(0)
{
}

Query::~Query(){}

const QSqlDatabase &Query::db() const
{
    static QSqlDatabase db;

    if (!db.isOpen()) {
        if (db.contains(m_currentConnectionName)) {
            db = QSqlDatabase::database(m_currentConnectionName);
        } else {
            db = QSqlDatabase::database();
        }
    }

    Q_ASSERT_X(db.isValid(), "ORM", "database connection not valid");
    Q_ASSERT_X(db.driver()->hasFeature(QSqlDriver::LastInsertId), "ORM", "database driver does not support last insert ID returning");
    Q_ASSERT_X(db.driver()->hasFeature(QSqlDriver::PreparedQueries), "ORM", "database driver does not support prepared queries");

    return db;
}

Query Query::select(const QString &entity, const QString &connection)
{
    return Query(entity, QuerySelect, connection);
}

Query Query::insert(const QString &entity, const QString &connection)
{
    return Query(entity, QueryInsert, connection);
}

Query Query::update(const QString &entity, const QString &connection)
{
    return Query(entity, QueryUpdate, connection);
}

Query Query::remove(const QString &entity, const QString &connection)
{
    return Query(entity, QueryRemove, connection);
}

void Query::createSelect(QSqlQuery &qr)
{
    QStringList sql;

    sql << "SELECT";

    if (m_isDistinct) {
        sql << "DISTINCT";
    }

    if (m_fields.count() == 0) {
        m_fields += entityFields(m_entity);
        for (int i = 0; i < m_joinEntities.count(); i++) {
            m_fields += entityFields(m_joinEntities.at(i));
        }
    }
    sql << m_fields.join(',');

    sql << "FROM" << m_entity;

    if (m_joinSql.count() > 0) {
        sql += m_joinSql;
    }

    if (!m_whereItems.isEmpty()) {
        sql << "WHERE";
        sql << m_whereItems;
    }

    if (!m_order.isEmpty()) {
        sql << "ORDER BY" << m_order;
    }

    if (m_limitCount != 0) {
        sql << "LIMIT" << QString("%1, %2").arg(m_limitCount, m_limitStart);
    }

    if (!m_group.isEmpty()) {
        sql << "GROUP BY" << m_group;
    }

    if (qr.prepare(sql.join(' '))) {
        for (int i = 0; i < m_whereBounds.count(); i++) {
            qr.addBindValue(m_whereBounds.at(i));
        }
    }
}

void Query::createInsert(QSqlQuery &qr)
{
    QStringList sql;
    sql << QString("INSERT INTO %1").arg(m_entity);

    QStringList fields, placeholders;
    for (int i=0; i < m_values.count(); i++) {
        if (m_values.field(i).value().isValid()) {
            fields << m_values.fieldName(i);
            placeholders << "?";
        }
    }

    sql << QString("(%1)").arg(fields.join(','))
        << QString("VALUES (%1)").arg(placeholders.join(','));

    if (qr.prepare(sql.join(' '))) {
        for (int i=0; i < fields.size(); i++) {
            int ix = m_values.indexOf(fields.at(i));
            qr.addBindValue(m_values.field(ix).value());
        }
    }
}

void Query::createUpdate(QSqlQuery &qr)
{
    QSqlIndex pi = db().primaryIndex(m_entity);

    QStringList sql;
    sql << QString("UPDATE %1").arg(m_entity)
        << "SET";

    QStringList fields,fields_sql;
    for (int i=0; i < m_values.count(); i++) {
        if (pi.contains(m_values.field(i).name())) continue;
        if (m_values.field(i).value().isValid()) {
            fields << m_values.field(i).name();
            fields_sql << QString("%1 = ?").arg(m_values.field(i).name());
        }
    }
    sql << fields_sql.join(',');

    if (!m_whereItems.isEmpty()) {
        sql << "WHERE";
        sql << m_whereItems;
    }

    if (qr.prepare(sql.join(' '))) {
        for (int i = 0; i < fields.size(); i++) {
            qr.addBindValue(m_values.field(fields.at(i)).value());
        }
        for (int i = 0; i < m_whereBounds.size(); i++) {
            qr.addBindValue(m_whereBounds.at(i));
        }
    }
}

void Query::createRemove(QSqlQuery &qr)
{
    QStringList sql;
    sql << QString("DELETE FROM %1").arg(m_entity);

    if (!m_whereItems.isEmpty()) {
        sql << "WHERE";
        sql << m_whereItems;
    }

    if (qr.prepare(sql.join(' '))) {
        for (int i = 0; i < m_whereBounds.size(); i++) {
            qr.addBindValue(m_whereBounds.at(i));
        }
    }
}

QString Query::escapeTableName(const QString &table)
{
    return db().driver()->escapeIdentifier(table, QSqlDriver::TableName);
}

QString Query::escapeFieldName(const QString &field)
{
    return db().driver()->escapeIdentifier(field, QSqlDriver::FieldName);
}

QStringList Query::entityFields(const QString &entity)
{
    QStringList fields_list;

    QSqlRecord rec = db().record(entity);
    for (int i = 0; i < rec.count(); i++) {
        QString pk_name = db().primaryIndex(entity).field(0).name();
        if (pk_name == rec.field(i).name()) {
            if (entity == m_entity) {
                fields_list << QString("%1.%2 AS %2").arg(escapeTableName(entity)).arg(escapeFieldName(pk_name));
            }
            continue;
        }
        QString postfix;
        QString full_name = QString("%1.%2").arg(entity).arg(rec.fieldName(i));
        if (entity == m_entity) {
            postfix = escapeFieldName(rec.fieldName(i));
        } else {
            // TODO hove to work this with driver side escaping
            postfix = QString("\"%1\"").arg(full_name);
        }
        fields_list << QString("%1 AS %2").arg(escapeTableName(full_name)).arg(postfix);
    }

    return fields_list;
}

QSqlQuery Query::make()
{
    QSqlQuery qr;

    switch (m_queryType) {
        case QuerySelect:
            createSelect(qr);
            break;
        case QueryInsert:
            createInsert(qr);
            break;
        case QueryUpdate:
            createUpdate(qr);
            break;
        case QueryRemove:
            createRemove(qr);
            break;
        default:
            break;
    }

    return qr;
}

Query &Query::where(const QString &sql, QVariantList binds)
{
    m_whereItems = sql;
    m_whereBounds = binds;
    return *this;
}

Query &Query::where(const QString &sql, const QVariant &bind)
{
    return where(sql, QVariantList() << bind);
}

Query &Query::where(const QString &sql)
{
    return where(sql, QVariantList());
}

Query &Query::distinct()
{
    m_isDistinct = true;
    return *this;
}

Query &Query::fields(const QString &fields_sql)
{
    m_fields << fields_sql;
    return *this;
}

Query &Query::fields(const QStringList &fields_list)
{
    return fields(fields_list.join(','));
}

Query &Query::fieldsFrom(const QString &entity)
{
    return fields(entityFields(entity));
}

Query &Query::order(const QString &fields_sql)
{
    m_order = fields_sql;
    return *this;
}

Query &Query::limit(int limit_count, int limit_start)
{
    m_limitCount = limit_count;
    m_limitStart = limit_start;
    return *this;
}

Query &Query::join(const QString &ent, const QString &fk, Query::JoinTypes join_type)
{
    QString join_type_str;
    switch (join_type) {
        case JoinLeft:
            join_type_str = "LEFT JOIN";
            break;
        case JoinRight:
            join_type_str = "RIGHT JOIN";
            break;
        case JoinInner:
            join_type_str = "INNER JOIN";
            break;
        default:
            join_type_str = "JOIN";
            break;
    }

    m_joinEntities << ent;
    m_joinSql << QString ("%1 %3 ON %2.%4 = %3.%5").arg(join_type_str)
                                                   .arg(m_entity)
                                                   .arg(ent)
                                                   .arg(fk)
                                                   .arg(db().primaryIndex(ent).field(0).name());

    return *this;
}

Query &Query::join(const QString &join_sql)
{
    m_joinSql << join_sql;
    return *this;
}

Query &Query::group(const QString &fields_sql)
{
    m_group = fields_sql;
    return *this;
}

Query &Query::values(const QSqlRecord &rec)
{
    m_values = rec;

    for (int i = 0; i < m_values.count(); i++) {
        if (m_values.field(i).isNull()) {
            m_values.remove(i);
        }
    }

    return *this;
}

Query &Query::values(const QMap<QString, QVariant> &values_map)
{
    QSqlRecord rec;
    QMapIterator<QString, QVariant> i(values_map);
    while (i.hasNext()) {
        i.next();
        QSqlField fld(i.key());
        fld.setValue(i.value());
        rec.append(fld);
    }
    return values(rec);
}

Query &Query::values(const QSqlField &field)
{
    QSqlRecord rec;
    rec.append(field);
    return values(rec);
}

Query &Query::values(const QString &name, const QVariant &value)
{
    QSqlField fld(name);
    fld.setValue(value);
    return values(fld);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- vim:set ts=4 sw=4 sts=4 noet: */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include <boost/program_options.hpp>

#include "isdstrip.h"
#include "sys/temporary_path.h"

namespace po = boost::program_options;

using namespace flint;

namespace {

void PrintNumOfColumns(std::uint32_t num_columns, const std::vector<std::uint32_t> &cv)
{
	std::cout << num_columns - static_cast<std::uint32_t>(cv.size()) << std::endl;
}

} // namespace

int main(int argc, char *argv[])
{
	po::options_description opts("options");
	po::positional_options_description popts;
	po::variables_map vm;
	std::string input_file, output_file;
	int print_help = 0;

	opts.add_options()
		("columns,c", "Put the resulting number of columns to stdout")
		("help,h", "Show this message")
		("output,o", po::value<std::string>(&output_file), "Output file name")
		("input", po::value<std::string>(&input_file), "Input file name");
	popts.add("input", 1);

	try {
		po::store(po::command_line_parser(argc, argv).options(opts).positional(popts).run(), vm);
		po::notify(vm);
		if (vm.count("help")) print_help = 1;
		if (vm.count("input") == 0) print_help = 2;
	} catch (const po::error &) {
		print_help = 2;
	}
	if (print_help != 0) {
		std::cerr << "usage: isdstrip [OPTIONS] PATH" << std::endl;
		std::cerr << opts << std::endl;
		return (print_help == 1) ? EXIT_SUCCESS : EXIT_FAILURE;
	}

	std::vector<std::uint32_t> cv;
	std::uint32_t num_columns = 0;
		const char *input_path = input_file.c_str();
		if (!isdstrip::ExtractConstantColumns(input_path, &num_columns, &cv)) {
			return EXIT_FAILURE;
		}
		if (vm.count("output")) {
			std::ofstream ofs(output_file.c_str(), std::ios::out|std::ios::binary);
			if (!ofs.is_open()) {
				std::cerr << "could not open output file: " << output_file << std::endl;
				return EXIT_FAILURE;
			}
			int r = isdstrip::Filter(input_path, cv, &ofs);
			ofs.close();
			if (r == EXIT_SUCCESS && vm.count("columns")) PrintNumOfColumns(num_columns, cv);
			return r;
		} else {
			char *output_path = nullptr;
			{
				std::unique_ptr<TemporaryPath> temp_path(new TemporaryPath("isdstrip"));
				output_path = temp_path->Touch();
				if (!output_path) {
					std::cerr << "could not create temporary path" << std::endl;
					return EXIT_FAILURE;
				}
			}
			std::ofstream ofs(output_path, std::ios::out|std::ios::binary);
			if (!ofs.is_open()) {
				std::cerr << "could not open output file: " << output_path << std::endl;
				remove(output_path);
				free(output_path);
				return EXIT_FAILURE;
			}
			int r = isdstrip::Filter(input_path, cv, &ofs);
			ofs.close();
			if (r == EXIT_SUCCESS) {
				// FIXME: thin possibility to fail to rename()
				remove(input_path);
				rename(output_path, input_path);
				if (vm.count("columns")) PrintNumOfColumns(num_columns, cv);
			} else {
				remove(output_path);
			}
			free(output_path);
			return r;
		}
}
<commit_msg>Fix indentation<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- vim:set ts=4 sw=4 sts=4 noet: */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include <boost/program_options.hpp>

#include "isdstrip.h"
#include "sys/temporary_path.h"

namespace po = boost::program_options;

using namespace flint;

namespace {

void PrintNumOfColumns(std::uint32_t num_columns, const std::vector<std::uint32_t> &cv)
{
	std::cout << num_columns - static_cast<std::uint32_t>(cv.size()) << std::endl;
}

} // namespace

int main(int argc, char *argv[])
{
	po::options_description opts("options");
	po::positional_options_description popts;
	po::variables_map vm;
	std::string input_file, output_file;
	int print_help = 0;

	opts.add_options()
		("columns,c", "Put the resulting number of columns to stdout")
		("help,h", "Show this message")
		("output,o", po::value<std::string>(&output_file), "Output file name")
		("input", po::value<std::string>(&input_file), "Input file name");
	popts.add("input", 1);

	try {
		po::store(po::command_line_parser(argc, argv).options(opts).positional(popts).run(), vm);
		po::notify(vm);
		if (vm.count("help")) print_help = 1;
		if (vm.count("input") == 0) print_help = 2;
	} catch (const po::error &) {
		print_help = 2;
	}
	if (print_help != 0) {
		std::cerr << "usage: isdstrip [OPTIONS] PATH" << std::endl;
		std::cerr << opts << std::endl;
		return (print_help == 1) ? EXIT_SUCCESS : EXIT_FAILURE;
	}

	std::vector<std::uint32_t> cv;
	std::uint32_t num_columns = 0;
	const char *input_path = input_file.c_str();
	if (!isdstrip::ExtractConstantColumns(input_path, &num_columns, &cv)) {
		return EXIT_FAILURE;
	}
	if (vm.count("output")) {
		std::ofstream ofs(output_file.c_str(), std::ios::out|std::ios::binary);
		if (!ofs.is_open()) {
			std::cerr << "could not open output file: " << output_file << std::endl;
			return EXIT_FAILURE;
		}
		int r = isdstrip::Filter(input_path, cv, &ofs);
		ofs.close();
		if (r == EXIT_SUCCESS && vm.count("columns")) PrintNumOfColumns(num_columns, cv);
		return r;
	} else {
		char *output_path = nullptr;
		{
			std::unique_ptr<TemporaryPath> temp_path(new TemporaryPath("isdstrip"));
			output_path = temp_path->Touch();
			if (!output_path) {
				std::cerr << "could not create temporary path" << std::endl;
				return EXIT_FAILURE;
			}
		}
		std::ofstream ofs(output_path, std::ios::out|std::ios::binary);
		if (!ofs.is_open()) {
			std::cerr << "could not open output file: " << output_path << std::endl;
			remove(output_path);
			free(output_path);
			return EXIT_FAILURE;
		}
		int r = isdstrip::Filter(input_path, cv, &ofs);
		ofs.close();
		if (r == EXIT_SUCCESS) {
			// FIXME: thin possibility to fail to rename()
			remove(input_path);
			rename(output_path, input_path);
			if (vm.count("columns")) PrintNumOfColumns(num_columns, cv);
		} else {
			remove(output_path);
		}
		free(output_path);
		return r;
	}
}
<|endoftext|>


<commit_before>/*
 * redsea - RDS decoder
 * Copyright (c) Oona Räisänen OH2EIQ (windyoona@gmail.com)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <getopt.h>
#include <iostream>

#include "config.h"
#include "src/common.h"
#include "src/block_sync.h"
#include "src/groups.h"

namespace redsea {

void PrintUsage() {
  std::cout <<
     "radio_command | ./src/redsea [OPTIONS]\n"
     "\n"
     "-b, --input-ascii      Input is ASCII bit stream (011010110...)\n"
     "-e, --feed-through     Echo the input signal to stdout and print\n"
     "                       decoded groups to stderr\n"
     "-f, --file             Input is an audio file\n"
     "-h, --input-hex        Input is hex groups in the RDS Spy format\n"
     "-x, --output-hex       Output is hex groups in the RDS Spy format\n"
     "-p, --show-partial     Display PS and RadioText before completely\n"
     "                       received (as partial_ps, partial_radiotext)\n"
     "-r, --samplerate       Set input sample frequency - will resample\n"
     "                       (slow) if this differs from 171000 Hz\n"
     "-u, --rbds             Use RBDS (North American) program types\n"
     "-l, --loctable DIR     Load TMC location table from a directory in TMC\n"
     "                       Exchange format\n"
     "-v, --version          Print version\n";
}

void PrintVersion() {
#ifdef DEBUG
  std::cout << PACKAGE_STRING << "-debug by OH2EIQ" << std::endl;
#else
  std::cout << PACKAGE_STRING << " by OH2EIQ" << std::endl;
#endif
}

Options GetOptions(int argc, char** argv) {
  redsea::Options options;

  static struct option long_options[] = {
    { "input-binary",  no_argument, 0, 'b'},
    { "feed-through",  no_argument, 0, 'e'},
    { "file",          1,           0, 'f'},
    { "input-hex",     no_argument, 0, 'h'},
    { "output-hex",    no_argument, 0, 'x'},
    { "show-partial",  no_argument, 0, 'p'},
    { "samplerate",    1,           0, 'r'},
    { "rbds",          no_argument, 0, 'u'},
    { "help",          no_argument, 0, '?'},
    { "loctable",      1,           0, 'l'},
    { "version",       no_argument, 0, 'v'},
    {0,                0,           0,  0}};

  int option_index = 0;
  int option_char;

  while ((option_char = getopt_long(argc, argv, "bef:hl:pr:uvx", long_options,
         &option_index)) >= 0) {
    switch (option_char) {
      case 'b':
        options.input_type = redsea::INPUT_ASCIIBITS;
        break;
      case 'e':
        options.feed_thru = true;
        break;
      case 'f':
#ifdef HAVE_SNDFILE
        options.sndfilename = std::string(optarg);
        options.input_type = redsea::INPUT_MPX_SNDFILE;
#else
        std::cerr << "Sorry, redsea was built without libsndfile."
                  << std::endl;
        options.just_exit = true;
#endif
        break;
      case 'h':
        options.input_type = redsea::INPUT_RDSSPY;
        break;
      case 'x':
        options.output_type = redsea::OUTPUT_HEX;
        break;
      case 'p':
        options.show_partial = true;
        break;
      case 'r':
        options.samplerate = std::atoi(optarg);
        if (options.samplerate < 128000.f) {
          std::cerr << "error: sample rate must be 128000 Hz or higher"
                    << std::endl;
          options.just_exit = true;
        }
        break;
      case 'u':
        options.rbds = true;
        break;
      case 'l':
        options.loctable_dir = std::string(optarg);
        break;
      case 'v':
        PrintVersion();
        options.just_exit = true;
        break;
      case '?':
      default:
        PrintUsage();
        options.just_exit = true;
        break;
    }
    if (options.just_exit)
      break;
  }

  if (options.feed_thru && options.input_type == INPUT_MPX_SNDFILE) {
    std::cerr << "error: feed-thru is not supported for audio file inputs"
              << std::endl;
    options.just_exit = true;
  }

  return options;
}

}  // namespace redsea

int main(int argc, char** argv) {
  redsea::Options options = redsea::GetOptions(argc, argv);

  if (options.just_exit)
    return EXIT_FAILURE;

#ifndef HAVE_LIQUID
  if (options.input_type == redsea::INPUT_MPX) {
    std::cerr << "can't demodulate MPX: redsea was compiled without liquid-dsp"
              << std::endl;
    return EXIT_FAILURE;
  }
#endif

  uint16_t pi = 0x0000, prev_new_pi = 0x0000, new_pi = 0x0000;
  redsea::BlockStream block_stream(options);
  redsea::Station station(pi, options);

  // Line buffering
  if (options.feed_thru)
    setvbuf(stderr, NULL, _IOLBF, 2048);
  else
    setvbuf(stdout, NULL, _IOLBF, 2048);

  while (!(std::cin.eof() || block_stream.eof())) {
    redsea::Group group = (options.input_type == redsea::INPUT_RDSSPY ?
        redsea::NextGroupRSpy(options.feed_thru) :
        block_stream.NextGroup());

    if (group.has_pi()) {
      // Repeated PI confirms change
      prev_new_pi = new_pi;
      new_pi = group.block(redsea::BLOCK1);

      if (new_pi == prev_new_pi || options.input_type == redsea::INPUT_RDSSPY) {
        if (new_pi != pi)
          station = redsea::Station(new_pi, options);
        pi = new_pi;
      } else {
        continue;
      }
    }

#ifdef DEBUG
    printf("b:%f,", block_stream.t());
#endif

    if (options.output_type == redsea::OUTPUT_HEX) {
      redsea::PrintHexGroup(group, options.feed_thru ? &std::cerr : &std::cout);
    } else {
      station.UpdateAndPrint(group, options.feed_thru ?
                             &std::cerr : &std::cout);
    }
  }

  return EXIT_SUCCESS;
}
<commit_msg>fix no-liquid build<commit_after>/*
 * redsea - RDS decoder
 * Copyright (c) Oona Räisänen OH2EIQ (windyoona@gmail.com)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <getopt.h>
#include <iostream>

#include "config.h"
#include "src/common.h"
#include "src/block_sync.h"
#include "src/groups.h"

namespace redsea {

void PrintUsage() {
  std::cout <<
     "radio_command | ./src/redsea [OPTIONS]\n"
     "\n"
     "-b, --input-ascii      Input is ASCII bit stream (011010110...)\n"
     "-e, --feed-through     Echo the input signal to stdout and print\n"
     "                       decoded groups to stderr\n"
     "-f, --file             Input is an audio file\n"
     "-h, --input-hex        Input is hex groups in the RDS Spy format\n"
     "-x, --output-hex       Output is hex groups in the RDS Spy format\n"
     "-p, --show-partial     Display PS and RadioText before completely\n"
     "                       received (as partial_ps, partial_radiotext)\n"
     "-r, --samplerate       Set input sample frequency - will resample\n"
     "                       (slow) if this differs from 171000 Hz\n"
     "-u, --rbds             Use RBDS (North American) program types\n"
     "-l, --loctable DIR     Load TMC location table from a directory in TMC\n"
     "                       Exchange format\n"
     "-v, --version          Print version\n";
}

void PrintVersion() {
#ifdef DEBUG
  std::cout << PACKAGE_STRING << "-debug by OH2EIQ" << std::endl;
#else
  std::cout << PACKAGE_STRING << " by OH2EIQ" << std::endl;
#endif
}

Options GetOptions(int argc, char** argv) {
  redsea::Options options;

  static struct option long_options[] = {
    { "input-binary",  no_argument, 0, 'b'},
    { "feed-through",  no_argument, 0, 'e'},
    { "file",          1,           0, 'f'},
    { "input-hex",     no_argument, 0, 'h'},
    { "output-hex",    no_argument, 0, 'x'},
    { "show-partial",  no_argument, 0, 'p'},
    { "samplerate",    1,           0, 'r'},
    { "rbds",          no_argument, 0, 'u'},
    { "help",          no_argument, 0, '?'},
    { "loctable",      1,           0, 'l'},
    { "version",       no_argument, 0, 'v'},
    {0,                0,           0,  0}};

  int option_index = 0;
  int option_char;

  while ((option_char = getopt_long(argc, argv, "bef:hl:pr:uvx", long_options,
         &option_index)) >= 0) {
    switch (option_char) {
      case 'b':
        options.input_type = redsea::INPUT_ASCIIBITS;
        break;
      case 'e':
        options.feed_thru = true;
        break;
      case 'f':
#ifdef HAVE_SNDFILE
        options.sndfilename = std::string(optarg);
        options.input_type = redsea::INPUT_MPX_SNDFILE;
#else
        std::cerr << "Sorry, redsea was built without libsndfile."
                  << std::endl;
        options.just_exit = true;
#endif
        break;
      case 'h':
        options.input_type = redsea::INPUT_RDSSPY;
        break;
      case 'x':
        options.output_type = redsea::OUTPUT_HEX;
        break;
      case 'p':
        options.show_partial = true;
        break;
      case 'r':
        options.samplerate = std::atoi(optarg);
        if (options.samplerate < 128000.f) {
          std::cerr << "error: sample rate must be 128000 Hz or higher"
                    << std::endl;
          options.just_exit = true;
        }
        break;
      case 'u':
        options.rbds = true;
        break;
      case 'l':
        options.loctable_dir = std::string(optarg);
        break;
      case 'v':
        PrintVersion();
        options.just_exit = true;
        break;
      case '?':
      default:
        PrintUsage();
        options.just_exit = true;
        break;
    }
    if (options.just_exit)
      break;
  }

  if (options.feed_thru && options.input_type == INPUT_MPX_SNDFILE) {
    std::cerr << "error: feed-thru is not supported for audio file inputs"
              << std::endl;
    options.just_exit = true;
  }

  return options;
}

}  // namespace redsea

int main(int argc, char** argv) {
  redsea::Options options = redsea::GetOptions(argc, argv);

  if (options.just_exit)
    return EXIT_FAILURE;

#ifndef HAVE_LIQUID
  if (options.input_type == redsea::INPUT_MPX_STDIN ||
      options.input_type == redsea::INPUT_MPX_SNDFILE) {
    std::cerr << "can't demodulate MPX: redsea was compiled without liquid-dsp"
              << std::endl;
    return EXIT_FAILURE;
  }
#endif

  uint16_t pi = 0x0000, prev_new_pi = 0x0000, new_pi = 0x0000;
  redsea::BlockStream block_stream(options);
  redsea::Station station(pi, options);

  // Line buffering
  if (options.feed_thru)
    setvbuf(stderr, NULL, _IOLBF, 2048);
  else
    setvbuf(stdout, NULL, _IOLBF, 2048);

  while (!(std::cin.eof() || block_stream.eof())) {
    redsea::Group group = (options.input_type == redsea::INPUT_RDSSPY ?
        redsea::NextGroupRSpy(options.feed_thru) :
        block_stream.NextGroup());

    if (group.has_pi()) {
      // Repeated PI confirms change
      prev_new_pi = new_pi;
      new_pi = group.block(redsea::BLOCK1);

      if (new_pi == prev_new_pi || options.input_type == redsea::INPUT_RDSSPY) {
        if (new_pi != pi)
          station = redsea::Station(new_pi, options);
        pi = new_pi;
      } else {
        continue;
      }
    }

#ifdef DEBUG
    printf("b:%f,", block_stream.t());
#endif

    if (options.output_type == redsea::OUTPUT_HEX) {
      redsea::PrintHexGroup(group, options.feed_thru ? &std::cerr : &std::cout);
    } else {
      station.UpdateAndPrint(group, options.feed_thru ?
                             &std::cerr : &std::cout);
    }
  }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/* vim: tabstop=2 shiftwidth=2 expandtab textwidth=80 linebreak wrap
 *
 * Copyright 2012 Matthew McCormick
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib> // EXIT_SUCCESS, atoi()
#include <getopt.h> // getopt_long

#include "version.h"
#include "graph.h"

// Tmux color lookup tables for the different metrics.
#include "luts.h"

#if defined(__APPLE__) && defined(__MACH__)
   // Apple osx system
   #include "osx/cpu.h"
   #include "osx/memory.h"
   #include "osx/load.h"
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
   // BSD system
   #define BSD_BASED 1
   #include "bsd/cpu.h"
   #include "bsd/load.h"
   #include "bsd/memory.h"
#else
   // assume linux system
   #include "linux/cpu.h"
   #include "linux/memory.h"
   #include "linux/load.h"
#endif

std::string cpu_string( unsigned int cpu_usage_delay, unsigned int graph_lines,
	bool use_colors = false )
{

  float percentage;

  //output stuff
  std::ostringstream oss;
  oss.precision( 1 );
  oss.setf( std::ios::fixed | std::ios::right );

  // get %
  percentage = cpu_percentage( cpu_usage_delay );

  if( use_colors )
  {
    oss << cpu_percentage_lut[static_cast<unsigned int>( percentage )];
  }

  if( graph_lines > 0)
  {
    oss << "[";
    oss << get_graph_by_percentage( unsigned( percentage ), graph_lines );
    oss << "]";
  }
  oss.width( 5 );
  oss << percentage;
  oss << "%";
  if( use_colors )
  {
    oss << "#[fg=default,bg=default]";
  }

  return oss.str();
}

void print_help()
{
  using std::cout;
  using std::endl;

  cout << "tmux-mem-cpu-load v" << tmux_mem_cpu_load_VERSION << endl
    << "Usage: tmux-mem-cpu-load [OPTIONS]\n\n"
    << "Available options:\n"
    << "-h, --help\n"
    << "\t Prints this help message\n"
    << "--colors\n"
    << "\tUse tmux colors in output\n"
    << "-i <value>, --interval <value>\n"
    << "\tSet tmux status refresh interval in seconds. Default: 1 second\n"
    << "-g <value>, --graph-lines <value>\n"
    << "\tSet how many lines should be drawn in a graph. Default: 10\n"
    << endl;
}

int main( int argc, char** argv )
{
  unsigned cpu_usage_delay = 990000;
  short graph_lines = 10; // max 32767 should be enough
  bool use_colors = false;

  static struct option long_options[] =
  {
    // Struct is a s follows:
    //   const char * name, int has_arg, int *flag, int val
    // if *flag is null, val is option identifier to use in switch()
    // otherwise it's a value to set the variable *flag points to
    { "help", no_argument, NULL, 'h' },
    { "colors", no_argument, NULL, 'c' },
    { "interval", required_argument, NULL, 'i' },
    { "graph-lines", required_argument, NULL, 'g' },
    { 0, 0, 0, 0 } // used to handle unknown long options
  };

  int c;
  // while c != -1
  while( (c = getopt_long( argc, argv, "hi:g:", long_options, NULL) ) != -1 )
  {
    switch( c )
    {
      case 'h': // --help, -h
        print_help();
        return EXIT_FAILURE;
        break;
      case 'c': // --colors
        use_colors = true;
        break;
      case 'i': // --interval, -i
        if( atoi( optarg ) < 1 )
          {
            std::cerr << "Status interval argument must be one or greater.\n";
            return EXIT_FAILURE;
          }
        cpu_usage_delay = atoi( optarg ) * 1000000 - 10000;
        break;
      case 'g': // --graph-lines, -g
        if( atoi( optarg ) < 0 )
          {
            std::cerr << "Graph lines argument must be zero or greater.\n";
            return EXIT_FAILURE;
          }
        graph_lines = atoi( optarg );
        break;
      case '?':
        // getopt_long prints error message automatically
        return EXIT_FAILURE;
        break;
      default:
        std::cout << "?? getopt returned character code 0 " << c << std::endl;
        return EXIT_FAILURE;
    }
  }
  // Detect old option specification and return and error message.
  if( argc > optind )
  {
    std::cout <<
      "The interval and graph lines options are now specified with flags.\n\n";
    print_help();
    return EXIT_FAILURE;
  }

  std::cout << mem_string( use_colors ) << ' '
    << cpu_string( cpu_usage_delay, graph_lines, use_colors ) << ' '
    << load_string( use_colors );

  return EXIT_SUCCESS;
}

<commit_msg>Print error message to std::cerr.<commit_after>/* vim: tabstop=2 shiftwidth=2 expandtab textwidth=80 linebreak wrap
 *
 * Copyright 2012 Matthew McCormick
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <cstdlib> // EXIT_SUCCESS, atoi()
#include <getopt.h> // getopt_long

#include "version.h"
#include "graph.h"

// Tmux color lookup tables for the different metrics.
#include "luts.h"

#if defined(__APPLE__) && defined(__MACH__)
   // Apple osx system
   #include "osx/cpu.h"
   #include "osx/memory.h"
   #include "osx/load.h"
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
   // BSD system
   #define BSD_BASED 1
   #include "bsd/cpu.h"
   #include "bsd/load.h"
   #include "bsd/memory.h"
#else
   // assume linux system
   #include "linux/cpu.h"
   #include "linux/memory.h"
   #include "linux/load.h"
#endif

std::string cpu_string( unsigned int cpu_usage_delay, unsigned int graph_lines,
	bool use_colors = false )
{

  float percentage;

  //output stuff
  std::ostringstream oss;
  oss.precision( 1 );
  oss.setf( std::ios::fixed | std::ios::right );

  // get %
  percentage = cpu_percentage( cpu_usage_delay );

  if( use_colors )
  {
    oss << cpu_percentage_lut[static_cast<unsigned int>( percentage )];
  }

  if( graph_lines > 0)
  {
    oss << "[";
    oss << get_graph_by_percentage( unsigned( percentage ), graph_lines );
    oss << "]";
  }
  oss.width( 5 );
  oss << percentage;
  oss << "%";
  if( use_colors )
  {
    oss << "#[fg=default,bg=default]";
  }

  return oss.str();
}

void print_help()
{
  using std::cout;
  using std::endl;

  cout << "tmux-mem-cpu-load v" << tmux_mem_cpu_load_VERSION << endl
    << "Usage: tmux-mem-cpu-load [OPTIONS]\n\n"
    << "Available options:\n"
    << "-h, --help\n"
    << "\t Prints this help message\n"
    << "--colors\n"
    << "\tUse tmux colors in output\n"
    << "-i <value>, --interval <value>\n"
    << "\tSet tmux status refresh interval in seconds. Default: 1 second\n"
    << "-g <value>, --graph-lines <value>\n"
    << "\tSet how many lines should be drawn in a graph. Default: 10\n"
    << endl;
}

int main( int argc, char** argv )
{
  unsigned cpu_usage_delay = 990000;
  short graph_lines = 10; // max 32767 should be enough
  bool use_colors = false;

  static struct option long_options[] =
  {
    // Struct is a s follows:
    //   const char * name, int has_arg, int *flag, int val
    // if *flag is null, val is option identifier to use in switch()
    // otherwise it's a value to set the variable *flag points to
    { "help", no_argument, NULL, 'h' },
    { "colors", no_argument, NULL, 'c' },
    { "interval", required_argument, NULL, 'i' },
    { "graph-lines", required_argument, NULL, 'g' },
    { 0, 0, 0, 0 } // used to handle unknown long options
  };

  int c;
  // while c != -1
  while( (c = getopt_long( argc, argv, "hi:g:", long_options, NULL) ) != -1 )
  {
    switch( c )
    {
      case 'h': // --help, -h
        print_help();
        return EXIT_FAILURE;
        break;
      case 'c': // --colors
        use_colors = true;
        break;
      case 'i': // --interval, -i
        if( atoi( optarg ) < 1 )
          {
            std::cerr << "Status interval argument must be one or greater.\n";
            return EXIT_FAILURE;
          }
        cpu_usage_delay = atoi( optarg ) * 1000000 - 10000;
        break;
      case 'g': // --graph-lines, -g
        if( atoi( optarg ) < 0 )
          {
            std::cerr << "Graph lines argument must be zero or greater.\n";
            return EXIT_FAILURE;
          }
        graph_lines = atoi( optarg );
        break;
      case '?':
        // getopt_long prints error message automatically
        return EXIT_FAILURE;
        break;
      default:
        std::cerr << "?? getopt returned character code 0 " << c << std::endl;
        return EXIT_FAILURE;
    }
  }
  // Detect old option specification and return and error message.
  if( argc > optind )
  {
    std::cout <<
      "The interval and graph lines options are now specified with flags.\n\n";
    print_help();
    return EXIT_FAILURE;
  }

  std::cout << mem_string( use_colors ) << ' '
    << cpu_string( cpu_usage_delay, graph_lines, use_colors ) << ' '
    << load_string( use_colors );

  return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before>/*  -*- mode: C++; c-file-style: "gnu" -*-
 *
 *  This file is part of KMail, the KDE mail client.
 *
 *  Copyright (c) 2002-2003 Carsten Pfeiffer <pfeiffer@kde.org>
 *  Copyright (c) 2003      Zack Rusin <zack@kde.org>
 *
 *  KMail is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License, version 2, as
 *  published by the Free Software Foundation.
 *
 *  KMail is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of this program with any edition of
 *  the Qt library by Trolltech AS, Norway (or with modified versions
 *  of Qt that use the same license as Qt), and distribute linked
 *  combinations including the two.  You must obey the GNU General
 *  Public License in all respects for all of the code used other than
 *  Qt.  If you modify this file, you may extend this exception to
 *  your version of the file, but you are not obligated to do so.  If
 *  you do not wish to do so, delete this exception statement from
 *  your version.
 */
#include "mailsourceviewer.h"
#include <QApplication>
#include <QIcon>
#include <kwindowsystem.h>

#include <QRegExp>
#include <QShortcut>
#include <kiconloader.h>

namespace KMail {

void MailSourceHighlighter::highlightBlock ( const QString & text ) {
  // all visible ascii except space and :
  const QRegExp regexp( "^([\\x21-9;-\\x7E]+:\\s)" );
  const int headersState = -1; // Also the initial State
  const int bodyState = 0;

  // keep the previous state
  setCurrentBlockState( previousBlockState() );
  // If a header is found
  if( regexp.indexIn( text ) != -1 )
  {
    // Content- header starts a new mime part, and therefore new headers
    // If a Content-* header is found, change State to headers until a blank line is found.
    if ( text.startsWith( "Content-" ) )
    {
      setCurrentBlockState( headersState );
    }
    // highligth it if in headers state
    if( ( currentBlockState() == headersState ) )
    {
      QFont font = document()->defaultFont ();
      font.setBold( true );
      setFormat( 0, regexp.matchedLength(), font );
    }
  }
  // Change to body state
  else if (text.isEmpty())
  {
    setCurrentBlockState( bodyState );
  }
}

MailSourceViewer::MailSourceViewer( QWidget *parent )
  : KTextBrowser( parent ), mSourceHighLighter( 0 )
{
  setAttribute( Qt::WA_DeleteOnClose );
  setLineWrapMode( QTextEdit::NoWrap );
  setTextInteractionFlags( Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard );

  // combining the shortcuts in one qkeysequence() did not work...
  QShortcut* shortcut = new QShortcut( this );
  shortcut->setKey( Qt::Key_Escape );
  connect( shortcut, SIGNAL( activated() ), SLOT( close() ) );

  shortcut = new QShortcut( this );
  shortcut->setKey( Qt::Key_W+Qt::CTRL );
  connect( shortcut, SIGNAL( activated() ), SLOT( close() ) );
  KWindowSystem::setIcons( winId(),
                  qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
                  IconSize( KIconLoader::Desktop ) ),
                  qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
                  IconSize( KIconLoader::Small ) ) );
  mSourceHighLighter = new MailSourceHighlighter( this );
}

MailSourceViewer::~MailSourceViewer()
{
  delete mSourceHighLighter; mSourceHighLighter = 0;
}

}
<commit_msg>SVN_SILENT pedantic coding style fix.<commit_after>/*  -*- mode: C++; c-file-style: "gnu" -*-
 *
 *  This file is part of KMail, the KDE mail client.
 *
 *  Copyright (c) 2002-2003 Carsten Pfeiffer <pfeiffer@kde.org>
 *  Copyright (c) 2003      Zack Rusin <zack@kde.org>
 *
 *  KMail is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License, version 2, as
 *  published by the Free Software Foundation.
 *
 *  KMail is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of this program with any edition of
 *  the Qt library by Trolltech AS, Norway (or with modified versions
 *  of Qt that use the same license as Qt), and distribute linked
 *  combinations including the two.  You must obey the GNU General
 *  Public License in all respects for all of the code used other than
 *  Qt.  If you modify this file, you may extend this exception to
 *  your version of the file, but you are not obligated to do so.  If
 *  you do not wish to do so, delete this exception statement from
 *  your version.
 */
#include "mailsourceviewer.h"
#include <QApplication>
#include <QIcon>
#include <kwindowsystem.h>

#include <QRegExp>
#include <QShortcut>
#include <kiconloader.h>

namespace KMail {

void MailSourceHighlighter::highlightBlock ( const QString & text ) {
  // all visible ascii except space and :
  const QRegExp regexp( "^([\\x21-9;-\\x7E]+:\\s)" );
  const int headersState = -1; // Also the initial State
  const int bodyState = 0;

  // keep the previous state
  setCurrentBlockState( previousBlockState() );
  // If a header is found
  if( regexp.indexIn( text ) != -1 )
  {
    // Content- header starts a new mime part, and therefore new headers
    // If a Content-* header is found, change State to headers until a blank line is found.
    if ( text.startsWith( "Content-" ) )
    {
      setCurrentBlockState( headersState );
    }
    // highligth it if in headers state
    if( ( currentBlockState() == headersState ) )
    {
      QFont font = document()->defaultFont ();
      font.setBold( true );
      setFormat( 0, regexp.matchedLength(), font );
    }
  }
  // Change to body state
  else if ( text.isEmpty() )
  {
    setCurrentBlockState( bodyState );
  }
}

MailSourceViewer::MailSourceViewer( QWidget *parent )
  : KTextBrowser( parent ), mSourceHighLighter( 0 )
{
  setAttribute( Qt::WA_DeleteOnClose );
  setLineWrapMode( QTextEdit::NoWrap );
  setTextInteractionFlags( Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard );

  // combining the shortcuts in one qkeysequence() did not work...
  QShortcut* shortcut = new QShortcut( this );
  shortcut->setKey( Qt::Key_Escape );
  connect( shortcut, SIGNAL( activated() ), SLOT( close() ) );

  shortcut = new QShortcut( this );
  shortcut->setKey( Qt::Key_W+Qt::CTRL );
  connect( shortcut, SIGNAL( activated() ), SLOT( close() ) );
  KWindowSystem::setIcons( winId(),
                  qApp->windowIcon().pixmap( IconSize( KIconLoader::Desktop ),
                  IconSize( KIconLoader::Desktop ) ),
                  qApp->windowIcon().pixmap( IconSize( KIconLoader::Small ),
                  IconSize( KIconLoader::Small ) ) );
  mSourceHighLighter = new MailSourceHighlighter( this );
}

MailSourceViewer::~MailSourceViewer()
{
  delete mSourceHighLighter; mSourceHighLighter = 0;
}

}
<|endoftext|>


<commit_before>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

int main (int argc, char** argv) {

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray;
  cvtColor(image, gray, CV_RGB2GRAY);

// this mask filters out areas with too many edges
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
//  imshow("canny mask", gray.mul(canny));

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  blur(image, flow, Size(50,50));
  absdiff(flow, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
//  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
//  imshow("dark mask", gray.mul(kindofdark));

  Mat mask = flow.mul(kindofdark).mul(canny);
// close the mask
  Mat smallMask;
  resize(mask, smallMask, Size(150,150));
  int t1 = 21;
  Mat erodeKernel = ellipticKernel(21);
  erode(smallMask, smallMask, erodeKernel);
  int t2 = tracker2+1-(tracker2%2);
  Mat dilateKernel = ellipticKernel(31);
  dilate(smallMask, smallMask, dilateKernel);
  resize(smallMask, smallMask, Size(width, height));
  bitwise_and(smallMask,mask,mask);
  imshow("morph mask", gray.mul(mask));

//  Moments lol = moments(mask, 1);
//  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
//  imshow("leimage", image);

/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  Mat classifyThis;
  bilateralFilter(gray, classifyThis, 15, 10, 1);
  equalizeHist(classifyThis, classifyThis);
  classifyThis = classifyThis.mul(mask);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, 2, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Point center( mouths[i].x + mouths[i].width*0.5, mouths[i].y + mouths[i].height*0.5 );
   ellipse( image, center, Size( mouths[i].width*0.5, mouths[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
  }
  imshow("MOUTH", image);
*/
  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

void morphFast(Mat inout, int smallsize = 100, int factor = 25, int eq = 1, int diler = 0) {
 int width, height;
 width = inout.size().width;
 height = inout.size().height;
 Mat downsample;
 resize(inout, downsample, Size(smallsize,smallsize));
 Mat kernel = ellipticKernel(factor);
 if (diler) {
  erode(downsample, downsample, kernel);
 } else {
  dilate(downsample, downsample, kernel);
 }
 if (eq) {
  equalizeHist(downsample, downsample);
 }
 resize(downsample, inout, Size(width, height));
}

int main (int argc, char** argv) {

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

 Mat background = cvQueryFrame(capture);
 background = background.clone();
 blur(background, background, Size(50,50));

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
// preprocess by rotating according to OVR roll
//  imshow("webcam", image);

// let's make multiple masks where 0=not mouth, 1=uncertain

// then multiply them together and multiply that with image
// and run haar classifier on image

  Mat gray, blurred_img;
  cvtColor(image, gray, CV_RGB2GRAY);
  blur(image, blurred_img, Size(50,50));

// this mask filters out areas with too many edges
  Mat canny;
  Canny(gray, canny, 50, 50, 3);
  blur(canny, canny, Size(width/20,height/20));
  bitwise_not(canny, canny);
  threshold(canny, canny, 200, 1, THRESH_BINARY);
  blur(canny*255, canny, Size(width/10, height/10));
  threshold(canny, canny, 220, 1, THRESH_BINARY);
//  imshow("canny mask", gray.mul(canny));

// this mask filters out areas which have not changed much
// background needs to be updated when person is not in frame
// use OVR SDK to do this later
  Mat flow;
  absdiff(blurred_img, background, flow);
  cvtColor(flow, flow, CV_RGB2GRAY);
  morphFast(flow);
  threshold(flow, flow, 60, 1, THRESH_BINARY);
//  imshow("flow mask", gray.mul(flow));

// this mask gets anything kind of dark (DK2) and dilates
  Mat kindofdark;
  equalizeHist(gray, kindofdark);
  threshold(kindofdark, kindofdark, 100, 1, THRESH_BINARY_INV);
  morphFast(kindofdark, 100, 17, 0);
//  imshow("dark mask", gray.mul(kindofdark));

  Mat mask = flow.mul(kindofdark).mul(canny);
// close the mask
  Mat smallMask;
  resize(mask, smallMask, Size(150,150));
  int t1 = 21;
  Mat erodeKernel = ellipticKernel(21);
  erode(smallMask, smallMask, erodeKernel);
  int t2 = tracker2+1-(tracker2%2);
  Mat dilateKernel = ellipticKernel(31);
  dilate(smallMask, smallMask, dilateKernel);
  resize(smallMask, smallMask, Size(width, height));
  bitwise_and(smallMask,mask,mask);
  imshow("morph mask", gray.mul(mask));

// update background with new morph mask
// average what we know is background with prior background
  Mat mask_;
  subtract(1,mask,mask_);
  Mat mask3, mask3_;
  channel[0] = mask;
  channel[1] = mask;
  channel[2] = mask;
  merge(channel, 3, mask3);
  channel[0] = mask_;
  channel[1] = mask_;
  channel[2] = mask_;
  merge(channel, 3, mask3_);

  background = background.mul(mask3) +
   (background.mul(mask3_) + blurred_img.mul(mask3_))/2;

  imshow("background", background);

//  Moments lol = moments(mask, 1);
//  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
//  imshow("leimage", image);

/*
  CascadeClassifier mouth_cascade;
  mouth_cascade.load("Mouth.xml");
  vector<Rect> mouths;
  Mat classifyThis;
  bilateralFilter(gray, classifyThis, 15, 10, 1);
  equalizeHist(classifyThis, classifyThis);
  classifyThis = classifyThis.mul(mask);
  mouth_cascade.detectMultiScale(classifyThis, mouths, 1.1, 2, CV_HAAR_SCALE_IMAGE);
  for (size_t i=0; i<mouths.size(); i++) {
   Point center( mouths[i].x + mouths[i].width*0.5, mouths[i].y + mouths[i].height*0.5 );
   ellipse( image, center, Size( mouths[i].width*0.5, mouths[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
  }
  imshow("MOUTH", image);
*/
  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>


<commit_before>/***************************************************************************
             filter_lnotes.cxx  -  Lotus Notes Structured Text mail import
                             -------------------
    begin                : Wed Feb 16, 2005
    copyright            : (C) 2005 by Robert Rockers
    email                : kconfigure@rockerssoft.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <config.h>

#include <klocale.h>
#include <kfiledialog.h>
#include <ktempfile.h>
#include <kdebug.h>
#include <qfileinfo.h>

#include "filter_lnotes.hxx"

/** Default constructor. */
FilterLNotes::FilterLNotes() :
        Filter( i18n("Import Lotus Notes Emails"),
                "Robert Rockers",
                i18n("
Lotus Notes Structured Text mail import filter
"
                     "
This filter will import Structure Text files from an exported Lotus Notes email "
                     "client into KMail. Use this filter if you want to import mails from Lotus or other "
                     "mailers that use Lotus Notes' Structured Text format.
"
                     "
Note: Since it is possible to recreate the folder structure, the imported "
                     "messages will be stored in subfolders named by the files they ame from under: "
                     "\"Sylpheed-Import\" in your local folder.
"))
{}

/** Destructor. */
FilterLNotes::~FilterLNotes() {
    endImport();
}

/**
 * Recursive import of The Bat! maildir.
 * @param info Information storage for the operation.
 */
void FilterLNotes::import(FilterInfo *info) {

    inf = info;
    currentFile = 1;
    totalFiles = 0;

    QStringList filenames = KFileDialog::getOpenFileNames( QDir::homeDirPath(), "*|" + i18n("All Files (*)"),
                                                           inf->parent() );
    totalFiles = filenames.count();
    inf->setOverall(0);

    // See filter_mbox.cxx for better reference.
    for ( QStringList::Iterator filename = filenames.begin(); filename != filenames.end(); ++filename ) {

        ++currentFile;
        info->addLog( i18n("Importing emails from %1").arg(*filename) );
        ImportLNotes( *filename );
        inf->setOverall( 100 * currentFile / totalFiles );
        if ( info->shouldTerminate() )
            break;
    }
}

/**
 * Import the files within a Folder.
 * @param file The name of the file to import.
 */
void FilterLNotes::ImportLNotes(const QString& file) {

    // See Filter_pmail.cxx for better reference

    // Format of a Lotus Notes 5 Structured Text Document w form feed
    // Each email begins with a custom Header Principal:
    // The Message ends with a 0c character

    // open the message
    QFile f(file);

    if (! f.open( QIODevice::ReadOnly ) ) {
        inf->alert( i18n("Unable to open %1, skipping").arg( file ) );
    } else {

        int ch = 0;
        int state = 0;
        int n = 0;
        KTempFile *tempfile = 0;

        // Get folder name
        QFileInfo filenameInfo( file );
        QString folder("LNotes-Import/" + filenameInfo.baseName(TRUE));
        inf->setTo(folder);

        // State machine to read the data in. The fgetc usage is probably terribly slow ...
        while ((ch = f.getch()) >= 0) {
            switch (state) {
                    // new message state
                case 0:
                    // open temp output file
                    tempfile = new KTempFile;
                    state = 1;
                    inf->setCurrent(i18n("Message %1").arg(n++));
                    if ( inf->shouldTerminate() )
                        return;
                    // fall through

                    // inside a message state
                case 1:
                    if (ch == 0x0c) {
                        // close file, send it
                        tempfile->close();

                        if(inf->removeDupMsg)
                            addMessage( inf, folder, tempfile->name() );
                        else
                            addMessage_fastImport( inf, folder, tempfile->name() );

                        tempfile->unlink();
                        delete tempfile;
                        state = 0;

                        int currentPercentage = (int) ( ( (float) f.at() / filenameInfo.size() ) * 100 );
                        inf->setCurrent( currentPercentage );
                        if ( inf->shouldTerminate() )
                            return;

                        break;
                    }
                    if (ch == 0x0d) {
                        break;
                    }
                    tempfile->file()->putch(ch);
                    break;
            }
        }

        // did Folder end without 0x1a at the end?
        if (state != 0) {
            tempfile->close();

            if(inf->removeDupMsg)
                addMessage( inf, folder, tempfile->name() );
            else
                addMessage_fastImport( inf, folder, tempfile->name() );

            tempfile->unlink();
            delete tempfile;
        }
        f.close();
    }
}
<commit_msg>forward port: Copy paste error in i18n.<commit_after>/***************************************************************************
             filter_lnotes.cxx  -  Lotus Notes Structured Text mail import
                             -------------------
    begin                : Wed Feb 16, 2005
    copyright            : (C) 2005 by Robert Rockers
    email                : kconfigure@rockerssoft.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <config.h>

#include <klocale.h>
#include <kfiledialog.h>
#include <ktempfile.h>
#include <kdebug.h>
#include <qfileinfo.h>

#include "filter_lnotes.hxx"

/** Default constructor. */
FilterLNotes::FilterLNotes() :
        Filter( i18n("Import Lotus Notes Emails"),
                "Robert Rockers",
                i18n("
Lotus Notes Structured Text mail import filter
"
                     "
This filter will import Structure Text files from an exported Lotus Notes email "
                     "client into KMail. Use this filter if you want to import mails from Lotus or other "
                     "mailers that use Lotus Notes' Structured Text format.
"
                     "
Note: Since it is possible to recreate the folder structure, the imported "
                     "messages will be stored in subfolders named by the files they ame from under: "
                     "\"LNotes-Import\" in your local folder.
"))
{}

/** Destructor. */
FilterLNotes::~FilterLNotes() {
    endImport();
}

/**
 * Recursive import of The Bat! maildir.
 * @param info Information storage for the operation.
 */
void FilterLNotes::import(FilterInfo *info) {

    inf = info;
    currentFile = 1;
    totalFiles = 0;

    QStringList filenames = KFileDialog::getOpenFileNames( QDir::homeDirPath(), "*|" + i18n("All Files (*)"),
                                                           inf->parent() );
    totalFiles = filenames.count();
    inf->setOverall(0);

    // See filter_mbox.cxx for better reference.
    for ( QStringList::Iterator filename = filenames.begin(); filename != filenames.end(); ++filename ) {

        ++currentFile;
        info->addLog( i18n("Importing emails from %1").arg(*filename) );
        ImportLNotes( *filename );
        inf->setOverall( 100 * currentFile / totalFiles );
        if ( info->shouldTerminate() )
            break;
    }
}

/**
 * Import the files within a Folder.
 * @param file The name of the file to import.
 */
void FilterLNotes::ImportLNotes(const QString& file) {

    // See Filter_pmail.cxx for better reference

    // Format of a Lotus Notes 5 Structured Text Document w form feed
    // Each email begins with a custom Header Principal:
    // The Message ends with a 0c character

    // open the message
    QFile f(file);

    if (! f.open( QIODevice::ReadOnly ) ) {
        inf->alert( i18n("Unable to open %1, skipping").arg( file ) );
    } else {

        int ch = 0;
        int state = 0;
        int n = 0;
        KTempFile *tempfile = 0;

        // Get folder name
        QFileInfo filenameInfo( file );
        QString folder("LNotes-Import/" + filenameInfo.baseName(TRUE));
        inf->setTo(folder);

        // State machine to read the data in. The fgetc usage is probably terribly slow ...
        while ((ch = f.getch()) >= 0) {
            switch (state) {
                    // new message state
                case 0:
                    // open temp output file
                    tempfile = new KTempFile;
                    state = 1;
                    inf->setCurrent(i18n("Message %1").arg(n++));
                    if ( inf->shouldTerminate() )
                        return;
                    // fall through

                    // inside a message state
                case 1:
                    if (ch == 0x0c) {
                        // close file, send it
                        tempfile->close();

                        if(inf->removeDupMsg)
                            addMessage( inf, folder, tempfile->name() );
                        else
                            addMessage_fastImport( inf, folder, tempfile->name() );

                        tempfile->unlink();
                        delete tempfile;
                        state = 0;

                        int currentPercentage = (int) ( ( (float) f.at() / filenameInfo.size() ) * 100 );
                        inf->setCurrent( currentPercentage );
                        if ( inf->shouldTerminate() )
                            return;

                        break;
                    }
                    if (ch == 0x0d) {
                        break;
                    }
                    tempfile->file()->putch(ch);
                    break;
            }
        }

        // did Folder end without 0x1a at the end?
        if (state != 0) {
            tempfile->close();

            if(inf->removeDupMsg)
                addMessage( inf, folder, tempfile->name() );
            else
                addMessage_fastImport( inf, folder, tempfile->name() );

            tempfile->unlink();
            delete tempfile;
        }
        f.close();
    }
}
<|endoftext|>


<commit_before>#include "webcam.hpp"
#include <chrono>

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

unsigned long long getMilliseconds() {
 return chrono::system_clock::now().time_since_epoch()/chrono::milliseconds(1);
}

int main (int argc, char** argv) {

/*****
 begin camera setup
*****/

 CvCapture* capture = 0;
 int width, height;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream config_file (".config");

 if (config_file.is_open()) {
// does not support corrupted .config

  string line;
  getline(config_file, line);
  istringstream(line)>>width;
  getline(config_file, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  config_file.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream config_file_out(".config");
  config_file_out << width;
  config_file_out << "\n";
  config_file_out << height;
  config_file_out << "\n";
  config_file_out.close();
 }

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

/*****
 end camera setup
*****/

/*****
 filter setup
*****/

 Mat acbg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated background
 Mat acbg_m(256, 256, CV_8UC1, Scalar(0));
// accumulated background mask

 Mat acfg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated foreground
 Mat acfg_t(256, 256, CV_8UC3, Scalar(0));
// accumulated foreground threshold

 Mat img_256_p(256, 256, CV_8UC3, Scalar(0,0,0));
// previous image
 Mat haar_t_p(256, 256, CV_8UC1, Scalar(1));
// previous possible locations for mouth

/*****
 end filter setup
*****/

/*****
 misc
*****/

 unsigned long long times[100];
 for (int i=0; i<100; i++)
  times[i] = 0;

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 unsigned long long timenow = getMilliseconds();

 bool keep_going = true;

 CascadeClassifier mouth_cascade;
 mouth_cascade.load("Mouth.xml");

/*****
 begin filter loop
*****/

 while (keep_going) {

  Mat image(cvQueryFrame(capture));
//  imshow("webcam", image);
// at some point preprocess by rotating according to OVR roll
// right now really annoying because of state variables

  Mat gray, img_256, gray_256;
  resize(image, img_256, Size(256, 256));
  cvtColor(image, gray, CV_RGB2GRAY);
  cvtColor(img_256, gray_256, CV_RGB2GRAY);

// this mask gets anything kind of dark (DK2) and dilates
// should work *great*
  Mat gr_m;
// gray mask
  equalizeHist(gray_256, gr_m);
  threshold(gr_m, gr_m, 215, 1, THRESH_BINARY);
  dilate(gr_m, gr_m, ellipticKernel(23));
  erode(gr_m, gr_m, ellipticKernel(45));

//  imshow("gray mask", gray_256.mul(1-gr_m));

  bitwise_or(acbg_m, gr_m, acbg_m);
//  imshow("accumulated bg mask", gray_256.mul(1-acbg_m));

// this mask watches for flow against accumulated bg
  Mat fl_m;
// flow mask
  absdiff(img_256, acbg, fl_m);
  cvtColor(fl_m, fl_m, CV_BGR2GRAY);
  fl_m = acbg_m.mul(fl_m);
  threshold(fl_m, fl_m, 45, 1, THRESH_BINARY_INV);
  erode(fl_m, fl_m, ellipticKernel(51));
//  imshow("flow mask", fl_m*255);

  Mat bg_m;
  bitwise_and(acbg_m, fl_m, bg_m);
  bitwise_or(gr_m, bg_m, bg_m);
//  imshow("bgm", bg_m*255);

// maybe do some morphological operations on bg_m?
// previously combined bg_m with its opening

// ugly way to compute:
// acbg = [acbg'.(1-bg_m)]+[((acbg'+img_256)/2).bg_m]
// find a nicer way later
// problem is masks are 1 channel while images are 3 channel

  Mat bg_m3;
  Mat tmp0[3];
  tmp0[0] = tmp0[1] = tmp0[2] = bg_m;
  merge(tmp0, 3, bg_m3);
//  imshow("bg_m3", bg_m3*255);
  acbg = acbg.mul(Scalar(1,1,1)-bg_m3) + (acbg/2+img_256/2).mul(bg_m3);
//  imshow("acbg", acbg);

//  imshow("bg mask", gray_256.mul(1-bg_m));

  Mat df_m;
// delta flow mask
  absdiff(img_256, img_256_p, df_m);
  cvtColor(df_m, df_m, CV_BGR2GRAY);
  threshold(df_m, df_m, tracker3*3, 1, THRESH_BINARY);
  imshow("delta flow mask", df_m*255);
  img_256_p = img_256.clone();

  Mat haar_m;
// bitwise_and(1 - bg_m, fg_m, haar_m);
  haar_m = 1 - bg_m;

// run haar classifier
  int scale = width/300;
  if (scale < 1)
   scale = 1;
// can't use 256x256 since haar isn't stretch invariant

  Mat thingy;
  resize(gray, thingy, Size(width/scale, height/scale));
  equalizeHist(thingy, thingy);
///////////////////
// need to change this after foreground stuff gets written

  vector<Rect> mouth_rects;
  resize(haar_m, haar_m, Size(width/scale, height/scale));

  thingy = thingy.mul(haar_m);
/////////////////

  mouth_cascade.detectMultiScale(thingy, mouth_rects, 1.1, 0, CV_HAAR_SCALE_IMAGE);
  Mat rect_image(height, width, CV_8UC1, Scalar(0));

  for (size_t i=0; i<mouth_rects.size(); i++) {
   Rect scaled(mouth_rects[i].x*scale, mouth_rects[i].y*scale, mouth_rects[i].width*scale,mouth_rects[i].height*scale);
   Mat new_rect(height, width, CV_8UC1, Scalar(0));
   rectangle(new_rect, scaled, Scalar(1), CV_FILLED);
   rect_image += new_rect;
  }

  double min_val, max_val;
  minMaxLoc(rect_image, &min_val, &max_val);

// or maybe equalize? this whole thing needs to be rewritten
// with the new fg and temporal coherence ideas

  Mat rect_thresh;
  threshold(rect_image, rect_thresh, max_val*0.9, 1, THRESH_BINARY);
  imshow("mouth", rect_thresh.mul(gray));

/*
  Moments m = moments(rect_thresh, 1);
  circle(image, Point(m.m10/m.m00,m.m01/m.m00),20,Scalar(128),30);
  imshow("centroid", image);
*/

  keep_going = (waitKey(1)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}

<commit_msg>hacking<commit_after>#include "webcam.hpp"
#include <chrono>

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

unsigned long long getMilliseconds() {
 return chrono::system_clock::now().time_since_epoch()/chrono::milliseconds(1);
}

int main (int argc, char** argv) {

/*****
 begin camera setup
*****/

 CvCapture* capture = 0;
 int width, height;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream config_file (".config");

 if (config_file.is_open()) {
// does not support corrupted .config

  string line;
  getline(config_file, line);
  istringstream(line)>>width;
  getline(config_file, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  config_file.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream config_file_out(".config");
  config_file_out << width;
  config_file_out << "\n";
  config_file_out << height;
  config_file_out << "\n";
  config_file_out.close();
 }

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

/*****
 end camera setup
*****/

/*****
 filter setup
*****/

 Mat acbg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated background
 Mat acbg_m(256, 256, CV_8UC1, Scalar(0));
// accumulated background mask

 Mat acfg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated foreground
 Mat acfg_t(256, 256, CV_8UC3, Scalar(0));
// accumulated foreground threshold

 Mat img_256_p(256, 256, CV_8UC3, Scalar(0,0,0));
// previous image
 Mat haar_t_p(256, 256, CV_8UC1, Scalar(1));
// previous possible locations for mouth

/*****
 end filter setup
*****/

/*****
 misc
*****/

 unsigned long long times[100];
 for (int i=0; i<100; i++)
  times[i] = 0;

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 unsigned long long timenow = getMilliseconds();

 bool keep_going = true;

 CascadeClassifier mouth_cascade;
 mouth_cascade.load("Mouth.xml");

/*****
 begin filter loop
*****/

 while (keep_going) {

  Mat image(cvQueryFrame(capture));
//  imshow("webcam", image);
// at some point preprocess by rotating according to OVR roll
// right now really annoying because of state variables

  Mat gray, img_256, gray_256;
  resize(image, img_256, Size(256, 256));
  cvtColor(image, gray, CV_RGB2GRAY);
  cvtColor(img_256, gray_256, CV_RGB2GRAY);

// this mask gets anything kind of dark (DK2) and dilates
// should work *great*
  Mat gr_m;
// gray mask
  equalizeHist(gray_256, gr_m);
  threshold(gr_m, gr_m, 215, 1, THRESH_BINARY);
  dilate(gr_m, gr_m, ellipticKernel(23));
  erode(gr_m, gr_m, ellipticKernel(45));

//  imshow("gray mask", gray_256.mul(1-gr_m));

  bitwise_or(acbg_m, gr_m, acbg_m);
//  imshow("accumulated bg mask", gray_256.mul(1-acbg_m));

// this mask watches for flow against accumulated bg
  Mat fl_m;
// flow mask
  absdiff(img_256, acbg, fl_m);
  cvtColor(fl_m, fl_m, CV_BGR2GRAY);
  fl_m = acbg_m.mul(fl_m);
  threshold(fl_m, fl_m, 45, 1, THRESH_BINARY_INV);
  erode(fl_m, fl_m, ellipticKernel(51));
//  imshow("flow mask", fl_m*255);

  Mat bg_m;
  bitwise_and(acbg_m, fl_m, bg_m);
  bitwise_or(gr_m, bg_m, bg_m);
//  imshow("bgm", bg_m*255);

// maybe do some morphological operations on bg_m?
// previously combined bg_m with its opening

// ugly way to compute:
// acbg = [acbg'.(1-bg_m)]+[((acbg'+img_256)/2).bg_m]
// find a nicer way later
// problem is masks are 1 channel while images are 3 channel

  Mat bg_m3;
  Mat tmp0[3];
  tmp0[0] = tmp0[1] = tmp0[2] = bg_m;
  merge(tmp0, 3, bg_m3);
//  imshow("bg_m3", bg_m3*255);
  acbg = acbg.mul(Scalar(1,1,1)-bg_m3) + (acbg/2+img_256/2).mul(bg_m3);
//  imshow("acbg", acbg);

//  imshow("bg mask", gray_256.mul(1-bg_m));

  Mat df_m;
// delta flow mask
  absdiff(img_256, img_256_p, df_m);
  cvtColor(df_m, df_m, CV_BGR2GRAY);
  threshold(df_m, df_m, 10, 1, THRESH_BINARY);
  int t1,t2;
  t1 = tracker1+1-(tracker1%2);
  if (t1<3) t1=3;
  if (t1>90) t1=91;
  t2 = tracker2+1-(tracker2%2);
  if (t2<3) t2=3;
  if (t2>90) t2=91;

  erode(df_m, df_m, ellipticKernel(t1, t2));
  imshow("delta flow mask", df_m*255);
  img_256_p = img_256.clone();

  Mat haar_m;
// bitwise_and(1 - bg_m, fg_m, haar_m);
  haar_m = 1 - bg_m;

// run haar classifier
  int scale = width/300;
  if (scale < 1)
   scale = 1;
// can't use 256x256 since haar isn't stretch invariant

  Mat thingy;
  resize(gray, thingy, Size(width/scale, height/scale));
  equalizeHist(thingy, thingy);
///////////////////
// need to change this after foreground stuff gets written

  vector<Rect> mouth_rects;
  resize(haar_m, haar_m, Size(width/scale, height/scale));

  thingy = thingy.mul(haar_m);
/////////////////

  mouth_cascade.detectMultiScale(thingy, mouth_rects, 1.1, 0, CV_HAAR_SCALE_IMAGE);
  Mat rect_image(height, width, CV_8UC1, Scalar(0));

  for (size_t i=0; i<mouth_rects.size(); i++) {
   Rect scaled(mouth_rects[i].x*scale, mouth_rects[i].y*scale, mouth_rects[i].width*scale,mouth_rects[i].height*scale);
   Mat new_rect(height, width, CV_8UC1, Scalar(0));
   rectangle(new_rect, scaled, Scalar(1), CV_FILLED);
   rect_image += new_rect;
  }

  double min_val, max_val;
  minMaxLoc(rect_image, &min_val, &max_val);

// or maybe equalize? this whole thing needs to be rewritten
// with the new fg and temporal coherence ideas

  Mat rect_thresh;
  threshold(rect_image, rect_thresh, max_val*0.9, 1, THRESH_BINARY);
  imshow("mouth", rect_thresh.mul(gray));

/*
  Moments m = moments(rect_thresh, 1);
  circle(image, Point(m.m10/m.m00,m.m01/m.m00),20,Scalar(128),30);
  imshow("centroid", image);
*/

  keep_going = (waitKey(1)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}

<|endoftext|>