<commit_before>#include <vector>
#include <fstream>
#include <string>
#include <utility>
#include <map>
#include <cmath>
#include <iostream>
#include <random>
#include <algorithm>

static const int kNbKinds = 30;
static const double kLearningRate = 0.1;

enum Kind {
    ADJ,
    ADJWH,
    ADV,
    ADVWH,
    CC,
    CLO,
    CLR,
    CLS,
    CS,
    DET,
    DETWH,
    ET,
    I,
    ID,
    NC,
    NPP,
    P,
    P_D,
    PONCT,
    PREF,
    PRO,
    PROREL,
    PROWH,
    U,
    V,
    VIMP,
    VINF,
    VPP,
    VPR,
    VS,
};

Kind TextToPOS(const std::string& str) {
    if (str =="ADJ") return ADJ;
    if (str =="ADJWH") return ADJWH;
    if (str =="ADV") return ADV;
    if (str =="ADVWH") return ADVWH;
    if (str =="CC") return CC;
    if (str =="CLO") return CLO;
    if (str =="CLR") return CLR;
    if (str =="CLS") return CLS;
    if (str =="CS") return CS;
    if (str =="DET") return DET;
    if (str =="DETWH") return DETWH;
    if (str =="ET") return ET;
    if (str =="I") return I;
    if (str =="ID") return ID;
    if (str =="NC") return NC;
    if (str =="NPP") return NPP;
    if (str =="P") return P;
    if (str =="P+D") return P_D;
    if (str =="PONCT") return PONCT;
    if (str =="PREF") return PREF;
    if (str =="PRO") return PRO;
    if (str =="PROREL") return PROREL;
    if (str =="PROWH") return PROWH;
    if (str =="U") return U;
    if (str =="V") return V;
    if (str =="VIMP") return VIMP;
    if (str =="VINF") return VINF;
    if (str =="VPP") return VPP;
    if (str =="VPR") return VPR;
    if (str =="VS") return VS;
    return (Kind)-1;
};

std::string POSToText(Kind pos) {
    if (pos == ADJ) return "ADJ";
    if (pos == ADJWH) return "ADJWH";
    if (pos == ADV) return "ADV";
    if (pos == ADVWH) return "ADVWH";
    if (pos == CC) return "CC";
    if (pos == CLO) return "CLO";
    if (pos == CLR) return "CLR";
    if (pos == CLS) return "CLS";
    if (pos == CS) return "CS";
    if (pos == DET) return "DET";
    if (pos == DETWH) return "DETWH";
    if (pos == ET) return "ET";
    if (pos == I) return "I";
    if (pos == ID) return "ID";
    if (pos == NC) return "NC";
    if (pos == NPP) return "NPP";
    if (pos == P) return "P";
    if (pos == P_D) return "P+D";
    if (pos == PONCT) return "PONCT";
    if (pos == PREF) return "PREF";
    if (pos == PRO) return "PRO";
    if (pos == PROREL) return "PROREL";
    if (pos == PROWH) return "PROWH";
    if (pos == U) return "U";
    if (pos == V) return "V";
    if (pos == VIMP) return "VIMP";
    if (pos == VINF) return "VINF";
    if (pos == VPP) return "VPP";
    if (pos == VPR) return "VPR";
    if (pos == VS) return "VS";
    return "ERROR";
};

typedef std::pair<unsigned int, Kind> TaggedWord;
typedef std::vector<TaggedWord> Document;

static const int kNbSuffixes = 26;
enum Suffix {
    /* ADV */
    MENT,
    MANT,
    ION,
    IONS,
    /* VERB */
    ISSONS,
    ISSIONS,
    ISSEZ,
    ISSIEZ,
    AIS,
    AIT,
    AIENT,
    ONT,
    ONS,
    ENT,
    ER,
    IR,
    INDRE,
    EZ,
    S,
    T,
    /* ADJ */
    IQUE,
    E,
    ES,
    EES,
    AUX,
    AL,
};

const char* suffixes_str[] = {
    /* ADV */
    "ment",
    "mant",
    "ion",
    "ions",
    /* VERB */
    "issons",
    "issez",
    "issions",
    "issiez",
    "ais",
    "ait",
    "aient",
    "ont",
    "ons",
    "ent",
    "er",
    "ir",
    "indre",
    "ez",
    "s",
    "t",
    /* ADJ */
    "ique",
    "é",
    "és",
    "ées",
    "aux",
    "al",
};

enum Caps {
    NO_CAPS,
    FIRST_LETTER_CAPS,
    ALL_CAPS,
};

struct WordFeatures {
    std::string as_string;
    Suffix suffix;
    unsigned int idx;
    Caps caps;

    WordFeatures() : suffix((Suffix)-1), idx(-1), caps(NO_CAPS) {}
    WordFeatures(const std::string& str) : as_string(str), idx(-1), caps(NO_CAPS) {}
};

std::map<unsigned int, WordFeatures> word_features;

inline bool ends_with(std::string const & value, std::string const & ending)
{
    if (ending.size() > value.size())
        return false;
    return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}

/* WORD WEIGHT */

std::map<unsigned int, double> word_weight[kNbKinds];

double WordF(Kind target, const WordFeatures& w) {
    return word_weight[target][w.idx];
}

void WordF_Backprop(const TaggedWord& w, const double* probabilities) {
    for (int k = 0; k < kNbKinds; ++k) {
        double target = (w.second == k) ? 1 : 0;
        word_weight[k][w.first] += kLearningRate * (target - probabilities[k]);
    }
}

/* SUFFIXES */

double suffixes[kNbKinds][kNbSuffixes];

double SuffixF(Kind target, const WordFeatures& w) {
    int word_suffix = w.suffix;
    if (word_suffix != -1)
        return suffixes[target][word_suffix];
    else
        return 0;
}

void SuffixF_Backprop(const TaggedWord& w, const double* probabilities) {
    int word_suffix = word_features[w.first].suffix;
    if (word_suffix == -1)
        return;

    for (int k = 0; k < kNbKinds; ++k) {
        double target = k == w.second ? 1 : 0;
        suffixes[k][word_suffix] += kLearningRate * (target - probabilities[k]);
    }
}

/* CAPITALIZATION */

double capitalization[kNbKinds][3];

double CapsF(Kind target, const WordFeatures& w) {
    return capitalization[target][w.caps];
}

void CapsF_Backprop(const TaggedWord& w, const WordFeatures& wf, const double* probabilities) {
    for (int k = 0; k < kNbKinds; ++k) {
        double target = k == w.second ? 1 : 0;
        capitalization[k][wf.caps] += kLearningRate * (target - probabilities[k]);
    }
}

double RunAllFeatures(Kind k, const WordFeatures& w) {
    double sum = 0;
    sum += WordF(k, w);
    sum += SuffixF(k, w);
    sum += CapsF(k, w);
    return sum;
}

Kind ComputeClass(const WordFeatures& w, double* probabilities) {
    double total = 0;
    for (int k = 0; k < kNbKinds; ++k) {
        probabilities[k] = std::exp(RunAllFeatures((Kind) k, w));
        total += probabilities[k];
    }

    int max = 0;
    for (int k = 0; k < kNbKinds; ++k) {
        probabilities[k] /= total;
        if (probabilities[k] > probabilities[max]) {
            max = k;
        }
    }
    return (Kind)max;
}

void Backprop(const TaggedWord& tw, const WordFeatures& wf, const double* probabilities) {
    WordF_Backprop(tw, probabilities);
    SuffixF_Backprop(tw, probabilities);
    CapsF_Backprop(tw, wf, probabilities);
}

double ComputeNLL(double* probas) {
    double nll = 0;
    for (int i = 0; i < kNbKinds; ++i) {
        nll += std::log(probas[i]);
    }
    return -nll;
}

std::map<std::string, int> dict;

WordFeatures BuildFeatures(const std::string& w) {
    WordFeatures features(w);

    features.suffix = (Suffix)-1;
    for (int i = 0; i < kNbSuffixes; ++i) {
        if (ends_with(w, suffixes_str[i])) {
            features.suffix = (Suffix) i;
            break;
        }
    }

    if (std::all_of(w.begin(), w.end(), ::isupper))
        features.caps = ALL_CAPS;
    else if (std::any_of(w.begin(), w.end(), ::isupper))
        features.caps = FIRST_LETTER_CAPS;

    std::transform(features.as_string.begin(), features.as_string.end(), features.as_string.begin(),
            ::tolower);
    auto res = dict.find(features.as_string);
    features.idx = res == dict.end() ? -1 : res->second;
    return features;
}

void Init() {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::normal_distribution<double> d(0, 1);

    for (int i = 0; i < kNbKinds; ++i) {
        for (int j = 0; j < kNbSuffixes; ++j) {
            suffixes[i][j] = d(gen);
        }

        for (int j = 0; j < 3; ++j) {
            capitalization[i][j] = d(gen);
        }
    }
}

Document BuildDocument(char* filename) {
    Document doc;

    std::ifstream input(filename);
    std::string w;
    std::string pos;
    unsigned int max_word_id = 0;

    std::random_device rd;
    std::mt19937 gen(rd());
    std::normal_distribution<double> d(0, 1);

    while (input) {
        unsigned word_id = max_word_id;
        input >> w;
        std::string case_i_w = w;
        std::transform(case_i_w.begin(), case_i_w.end(), case_i_w.begin(), ::tolower);
        auto res = dict.insert(std::make_pair(case_i_w, max_word_id));
        if (!res.second) {
            word_id = res.first->second;
        } else {
            for (int k = 0; k < kNbKinds; ++k) {
                word_weight[k][word_id] = d(gen);
            }
            word_features[word_id] = BuildFeatures(w);
            ++max_word_id;
        }
        input >> pos;

        doc.push_back(std::make_pair(word_id, TextToPOS(pos)));
    }
    return doc;
}

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "Usage: ./" << argv[0] << " <training set>\n";
        return 1;
    }
    Init();
    Document doc = BuildDocument(argv[1]);

    for (int epoch = 0; epoch < 5; ++epoch) {
        double nll = 0;
        double probas[kNbKinds];
        int nb_correct = 0;
        int nb_tokens = 0;
        for (size_t i = 0; i < doc.size(); ++i) {
            const WordFeatures& wf = word_features[doc[i].first];
            Kind predicted = ComputeClass(wf, probas);
            nb_correct += predicted == doc[i].second ? 1 : 0;
            ++nb_tokens;

            nll += ComputeNLL(probas);

            Backprop(doc[i], wf, probas);
            if (i % 10000 == 0) {
                std::cout << nb_correct << " / " << nb_tokens << " (" << ((double) nb_correct *100 / nb_tokens) << "%)" << std::endl;
            }
        }
        std::cout << nll << "\n" << nb_correct << " / " << nb_tokens << "\n=======\n";
    }

    while (std::cin) {
        std::string w;
        std::cin >> w;

        std::cout << w << ":\n";

        double probas[kNbKinds];
        WordFeatures wf = BuildFeatures(w);

        if (wf.idx != (unsigned int) -1)
            std::cout << "  idx: " << wf.idx << "\n";

        Kind k = ComputeClass(wf, probas);
        std::cout << "  POS: " << POSToText(k) << " (confidence: " << probas[k] *100 << " %)\n";
    }

    return 0;
}
<commit_msg>map changed to vector, constant for -1<commit_after>#include <vector>
#include <fstream>
#include <string>
#include <utility>
#include <map>
#include <cmath>
#include <iostream>
#include <random>
#include <algorithm>

static const int kVocabSize = 100000;
static const int kNbKinds = 30;
static const double kLearningRate = 0.1;
static const unsigned int kNotFound = -1;

enum Kind {
    ADJ,
    ADJWH,
    ADV,
    ADVWH,
    CC,
    CLO,
    CLR,
    CLS,
    CS,
    DET,
    DETWH,
    ET,
    I,
    ID,
    NC,
    NPP,
    P,
    P_D,
    PONCT,
    PREF,
    PRO,
    PROREL,
    PROWH,
    U,
    V,
    VIMP,
    VINF,
    VPP,
    VPR,
    VS,
};

Kind TextToPOS(const std::string& str) {
    if (str =="ADJ") return ADJ;
    if (str =="ADJWH") return ADJWH;
    if (str =="ADV") return ADV;
    if (str =="ADVWH") return ADVWH;
    if (str =="CC") return CC;
    if (str =="CLO") return CLO;
    if (str =="CLR") return CLR;
    if (str =="CLS") return CLS;
    if (str =="CS") return CS;
    if (str =="DET") return DET;
    if (str =="DETWH") return DETWH;
    if (str =="ET") return ET;
    if (str =="I") return I;
    if (str =="ID") return ID;
    if (str =="NC") return NC;
    if (str =="NPP") return NPP;
    if (str =="P") return P;
    if (str =="P+D") return P_D;
    if (str =="PONCT") return PONCT;
    if (str =="PREF") return PREF;
    if (str =="PRO") return PRO;
    if (str =="PROREL") return PROREL;
    if (str =="PROWH") return PROWH;
    if (str =="U") return U;
    if (str =="V") return V;
    if (str =="VIMP") return VIMP;
    if (str =="VINF") return VINF;
    if (str =="VPP") return VPP;
    if (str =="VPR") return VPR;
    if (str =="VS") return VS;
    return (Kind)kNotFound;
};

std::string POSToText(Kind pos) {
    if (pos == ADJ) return "ADJ";
    if (pos == ADJWH) return "ADJWH";
    if (pos == ADV) return "ADV";
    if (pos == ADVWH) return "ADVWH";
    if (pos == CC) return "CC";
    if (pos == CLO) return "CLO";
    if (pos == CLR) return "CLR";
    if (pos == CLS) return "CLS";
    if (pos == CS) return "CS";
    if (pos == DET) return "DET";
    if (pos == DETWH) return "DETWH";
    if (pos == ET) return "ET";
    if (pos == I) return "I";
    if (pos == ID) return "ID";
    if (pos == NC) return "NC";
    if (pos == NPP) return "NPP";
    if (pos == P) return "P";
    if (pos == P_D) return "P+D";
    if (pos == PONCT) return "PONCT";
    if (pos == PREF) return "PREF";
    if (pos == PRO) return "PRO";
    if (pos == PROREL) return "PROREL";
    if (pos == PROWH) return "PROWH";
    if (pos == U) return "U";
    if (pos == V) return "V";
    if (pos == VIMP) return "VIMP";
    if (pos == VINF) return "VINF";
    if (pos == VPP) return "VPP";
    if (pos == VPR) return "VPR";
    if (pos == VS) return "VS";
    return "ERROR";
};

typedef std::pair<unsigned int, Kind> TaggedWord;
typedef std::vector<TaggedWord> Document;

static const int kNbSuffixes = 26;
enum Suffix {
    /* ADV */
    MENT,
    MANT,
    ION,
    IONS,
    /* VERB */
    ISSONS,
    ISSIONS,
    ISSEZ,
    ISSIEZ,
    AIS,
    AIT,
    AIENT,
    ONT,
    ONS,
    ENT,
    ER,
    IR,
    INDRE,
    EZ,
    S,
    T,
    /* ADJ */
    IQUE,
    E,
    ES,
    EES,
    AUX,
    AL,
};

const char* suffixes_str[] = {
    /* ADV */
    "ment",
    "mant",
    "ion",
    "ions",
    /* VERB */
    "issons",
    "issez",
    "issions",
    "issiez",
    "ais",
    "ait",
    "aient",
    "ont",
    "ons",
    "ent",
    "er",
    "ir",
    "indre",
    "ez",
    "s",
    "t",
    /* ADJ */
    "ique",
    "é",
    "és",
    "ées",
    "aux",
    "al",
};

enum Caps {
    NO_CAPS,
    FIRST_LETTER_CAPS,
    ALL_CAPS,
};

struct WordFeatures {
    std::string as_string;
    Suffix suffix;
    unsigned int idx;
    Caps caps;

    WordFeatures() : suffix((Suffix)kNotFound), idx(kNotFound), caps(NO_CAPS) {}
    WordFeatures(const std::string& str) : as_string(str), idx(kNotFound), caps(NO_CAPS) {}
};

std::vector<WordFeatures> word_features(kVocabSize, WordFeatures());

inline bool ends_with(std::string const & value, std::string const & ending)
{
    if (ending.size() > value.size())
        return false;
    return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
}

/* WORD WEIGHT */

std::vector<double> word_weight[kNbKinds];

double WordF(Kind target, const WordFeatures& w) {
    if (w.idx == kNotFound)
        return 0;

    return word_weight[target][w.idx];
}

void WordF_Backprop(const TaggedWord& w, const double* probabilities) {
    if (w.first == kNotFound)
        return;

    for (int k = 0; k < kNbKinds; ++k) {
        double target = (w.second == k) ? 1 : 0;
        word_weight[k][w.first] += kLearningRate * (target - probabilities[k]);
    }
}

/* SUFFIXES */

double suffixes[kNbKinds][kNbSuffixes];

double SuffixF(Kind target, const WordFeatures& w) {
    unsigned int word_suffix = w.suffix;
    if (word_suffix != kNotFound)
        return suffixes[target][word_suffix];
    else
        return 0;
}

void SuffixF_Backprop(const TaggedWord& w, const double* probabilities) {
    unsigned int word_suffix = word_features[w.first].suffix;
    if (word_suffix == kNotFound)
        return;

    for (int k = 0; k < kNbKinds; ++k) {
        double target = k == w.second ? 1 : 0;
        suffixes[k][word_suffix] += kLearningRate * (target - probabilities[k]);
    }
}

/* CAPITALIZATION */

double capitalization[kNbKinds][3];

double CapsF(Kind target, const WordFeatures& w) {
    return capitalization[target][w.caps];
}

void CapsF_Backprop(const TaggedWord& w, const WordFeatures& wf, const double* probabilities) {
    for (int k = 0; k < kNbKinds; ++k) {
        double target = k == w.second ? 1 : 0;
        capitalization[k][wf.caps] += kLearningRate * (target - probabilities[k]);
    }
}

double RunAllFeatures(Kind k, const WordFeatures& w) {
    double sum = 0;
    sum += WordF(k, w);
    sum += SuffixF(k, w);
    sum += CapsF(k, w);
    return sum;
}

Kind ComputeClass(const WordFeatures& w, double* probabilities) {
    double total = 0;
    for (int k = 0; k < kNbKinds; ++k) {
        probabilities[k] = std::exp(RunAllFeatures((Kind) k, w));
        total += probabilities[k];
    }

    int max = 0;
    for (int k = 0; k < kNbKinds; ++k) {
        probabilities[k] /= total;
        if (probabilities[k] > probabilities[max]) {
            max = k;
        }
    }
    return (Kind)max;
}

void Backprop(const TaggedWord& tw, const WordFeatures& wf, const double* probabilities) {
    WordF_Backprop(tw, probabilities);
    SuffixF_Backprop(tw, probabilities);
    CapsF_Backprop(tw, wf, probabilities);
}

double ComputeNLL(double* probas) {
    double nll = 0;
    for (int i = 0; i < kNbKinds; ++i) {
        nll += std::log(probas[i]);
    }
    return -nll;
}

std::map<std::string, int> dict;

WordFeatures BuildFeatures(const std::string& w) {
    WordFeatures features(w);

    features.suffix = (Suffix)kNotFound;
    for (int i = 0; i < kNbSuffixes; ++i) {
        if (ends_with(w, suffixes_str[i])) {
            features.suffix = (Suffix) i;
            break;
        }
    }

    if (std::all_of(w.begin(), w.end(), ::isupper))
        features.caps = ALL_CAPS;
    else if (std::any_of(w.begin(), w.end(), ::isupper))
        features.caps = FIRST_LETTER_CAPS;

    std::transform(features.as_string.begin(), features.as_string.end(), features.as_string.begin(),
            ::tolower);
    auto res = dict.find(features.as_string);
    features.idx = res == dict.end() ? kNotFound : res->second;
    return features;
}

void Init() {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::normal_distribution<double> d(0, 1);

    for (int i = 0; i < kNbKinds; ++i) {
        for (int j = 0; j < kNbSuffixes; ++j) {
            suffixes[i][j] = d(gen);
        }

        for (int j = 0; j < 3; ++j) {
            capitalization[i][j] = d(gen);
        }

        word_weight[i].resize(kVocabSize);
        for (int j = 0; j < kVocabSize; ++j) {
            word_weight[i][j] = d(gen);
        }
    }
}

Document BuildDocument(char* filename) {
    Document doc;

    std::ifstream input(filename);
    std::string w;
    std::string pos;
    unsigned int max_word_id = 0;

    while (input) {
        unsigned word_id = max_word_id;
        input >> w;
        std::string case_i_w = w;
        std::transform(case_i_w.begin(), case_i_w.end(), case_i_w.begin(), ::tolower);
        auto res = dict.insert(std::make_pair(case_i_w, max_word_id));
        if (!res.second) {
            word_id = res.first->second;
        } else {
            word_features[word_id] = BuildFeatures(w);
            ++max_word_id;
        }
        input >> pos;

        doc.push_back(std::make_pair(word_id, TextToPOS(pos)));
    }
    return doc;
}

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "Usage: ./" << argv[0] << " <training set>\n";
        return 1;
    }
    Init();
    Document doc = BuildDocument(argv[1]);

    for (int epoch = 0; epoch < 5; ++epoch) {
        double nll = 0;
        double probas[kNbKinds];
        int nb_correct = 0;
        int nb_tokens = 0;
        for (size_t i = 0; i < doc.size(); ++i) {
            const WordFeatures& wf = word_features[doc[i].first];
            Kind predicted = ComputeClass(wf, probas);
            nb_correct += predicted == doc[i].second ? 1 : 0;
            ++nb_tokens;

            nll += ComputeNLL(probas);

            Backprop(doc[i], wf, probas);
            if (i % 10000 == 0) {
                std::cout << nb_correct << " / " << nb_tokens << " (" << ((double) nb_correct *100 / nb_tokens) << "%)" << std::endl;
            }
        }
        std::cout << nll << "\n" << nb_correct << " / " << nb_tokens << "\n=======\n";
    }

    while (std::cin) {
        std::string w;
        std::cin >> w;

        std::cout << w << ":\n";

        double probas[kNbKinds];
        WordFeatures wf = BuildFeatures(w);

        if (wf.idx != kNotFound)
            std::cout << "  idx: " << wf.idx << "\n";

        Kind k = ComputeClass(wf, probas);
        std::cout << "  POS: " << POSToText(k) << " (confidence: " << probas[k] *100 << " %)\n";
    }

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>extensions: Use appropriate OUString functions on string constants<commit_after><|endoftext|>


<commit_before>#include "pch.h"
#include "FileLogger.h"

using namespace PinnedDownClient::Core;
using namespace PinnedDownClient::Util;

FileLogger::FileLogger(LogLevel logLevel, const wchar_t* const logFileName) : Logger(logLevel)
{
	StorageFolder^ temporaryFolder = ApplicationData::Current->TemporaryFolder;

	create_task(temporaryFolder->CreateFileAsync(ref new Platform::String(logFileName), CreationCollisionOption::ReplaceExisting))
		.then([this](StorageFile^ logFile) {
		this->logFile = logFile;
	});
}

FileLogger::~FileLogger()
{
	this->Flush();
}

void FileLogger::WriteLog(LogLevel logLevel, const wchar_t* const message)
{
	this->logBuffer += message;
}

void FileLogger::Flush()
{
	if (this->logFile != nullptr) {
		FileIO::AppendTextAsync(this->logFile, ref new Platform::String(this->logBuffer.c_str()));
	}

	this->logBuffer.clear();
}<commit_msg>ADDED: Logging - Timestamps to log output.<commit_after>#include "pch.h"
#include "FileLogger.h"

using namespace PinnedDownClient::Core;
using namespace PinnedDownClient::Util;

FileLogger::FileLogger(LogLevel logLevel, const wchar_t* const logFileName) : Logger(logLevel)
{
	StorageFolder^ temporaryFolder = ApplicationData::Current->TemporaryFolder;

	create_task(temporaryFolder->CreateFileAsync(ref new Platform::String(logFileName), CreationCollisionOption::ReplaceExisting))
		.then([this](StorageFile^ logFile) {
		this->logFile = logFile;
	});
}

FileLogger::~FileLogger()
{
	this->Flush();
}

void FileLogger::WriteLog(LogLevel logLevel, const wchar_t* const message)
{
	// Get current time.
	SYSTEMTIME st;
	GetSystemTime(&st);

	// Format string.
	wchar_t buffer[256];
	swprintf(buffer, 256, L"[%02d-%02d-%d %02d:%02d:%02d] ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

	this->logBuffer += std::wstring(buffer) + message;
}

void FileLogger::Flush()
{
	if (this->logFile != nullptr) {
		FileIO::AppendTextAsync(this->logFile, ref new Platform::String(this->logBuffer.c_str()));
	}

	this->logBuffer.clear();
}<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/debugger/devtools_window_win.h"

#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_view.h"
#include "chrome/views/window.h"

// static
DevToolsWindow* DevToolsWindow::Create(DevToolsInstanceDescriptor* descriptor) {
  DevToolsView* view = new DevToolsView(descriptor);
  DevToolsWindowWin* window = new DevToolsWindowWin(view);
  descriptor->SetDevToolsWindow(window);
  views::Window::CreateChromeWindow(NULL, gfx::Rect(), window);
  return window;
}

DevToolsWindowWin::DevToolsWindowWin(DevToolsView* view)
    : tools_view_(view) {
}

DevToolsWindowWin::~DevToolsWindowWin() {
  DCHECK(!tools_view_);
}

void DevToolsWindowWin::Show() {
  if (window()) {
    window()->Show();
  } else {
    NOTREACHED();
  }
}

void DevToolsWindowWin::Close() {
  if (window()) {
    window()->Close();
  } else {
    NOTREACHED();
  }
}

std::wstring DevToolsWindowWin::GetWindowTitle() const {
  return L"Developer Tools";
}

void DevToolsWindowWin::WindowClosing() {
  if (tools_view_) {
    ReleaseWindow();
    tools_view_->OnWindowClosing();
    tools_view_ = NULL;
  } else {
    NOTREACHED() << "WindowClosing called twice.";
  }
}

bool DevToolsWindowWin::CanResize() const {
  return true;
}

views::View* DevToolsWindowWin::GetContentsView() {
  return tools_view_;
}

void DevToolsWindowWin::DeleteDelegate() {
  DCHECK(!tools_view_) << "WindowClosing should have been called.";
  delete this;
}
<commit_msg>bustage fix - file moved<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/debugger/devtools_window_win.h"

#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_view.h"
#include "chrome/views/window/window.h"

// static
DevToolsWindow* DevToolsWindow::Create(DevToolsInstanceDescriptor* descriptor) {
  DevToolsView* view = new DevToolsView(descriptor);
  DevToolsWindowWin* window = new DevToolsWindowWin(view);
  descriptor->SetDevToolsWindow(window);
  views::Window::CreateChromeWindow(NULL, gfx::Rect(), window);
  return window;
}

DevToolsWindowWin::DevToolsWindowWin(DevToolsView* view)
    : tools_view_(view) {
}

DevToolsWindowWin::~DevToolsWindowWin() {
  DCHECK(!tools_view_);
}

void DevToolsWindowWin::Show() {
  if (window()) {
    window()->Show();
  } else {
    NOTREACHED();
  }
}

void DevToolsWindowWin::Close() {
  if (window()) {
    window()->Close();
  } else {
    NOTREACHED();
  }
}

std::wstring DevToolsWindowWin::GetWindowTitle() const {
  return L"Developer Tools";
}

void DevToolsWindowWin::WindowClosing() {
  if (tools_view_) {
    ReleaseWindow();
    tools_view_->OnWindowClosing();
    tools_view_ = NULL;
  } else {
    NOTREACHED() << "WindowClosing called twice.";
  }
}

bool DevToolsWindowWin::CanResize() const {
  return true;
}

views::View* DevToolsWindowWin::GetContentsView() {
  return tools_view_;
}

void DevToolsWindowWin::DeleteDelegate() {
  DCHECK(!tools_view_) << "WindowClosing should have been called.";
  delete this;
}
<|endoftext|>


<commit_before>//
//  TimedEventLoop.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 29/07/2016.
//  Copyright © 2016 Thomas Harte. All rights reserved.
//

#ifndef TimedEventLoop_hpp
#define TimedEventLoop_hpp

#include "Storage.hpp"
#include "../ClockReceiver/ClockReceiver.hpp"
#include "../SignalProcessing/Stepper.hpp"

#include <memory>

namespace Storage {

	/*!
		Provides a mechanism for arbitrarily timed events to be processed according to a fixed-base
		discrete clock signal, ensuring correct timing.

		Subclasses are responsible for calling @c set_next_event_time_interval to establish the time
		until a next event; @c process_next_event will be called when that event occurs, with progression
		determined via @c run_for.

		Due to the aggregation of total timing information between events — e.g. if an event loop has
		a clock rate of 1000 ticks per second and a steady stream of events that occur 10,000 times a second,
		bookkeeping is necessary to ensure that 10 events are triggered per tick — subclasses should call
		@c reset_timer if there is a discontinuity in events.

		Subclasses may also call @c jump_to_next_event to cause the next event to be communicated instantly.

		Subclasses are therefore expected to call @c set_next_event_time_interval upon obtaining an event stream,
		and again in response to each call to @c process_next_event while events are ongoing. They may use
		@c reset_timer to initiate a distinctly-timed stream or @c jump_to_next_event to short-circuit the timing
		loop and fast forward immediately to the next event.
	*/
	class TimedEventLoop {
		public:
			/*!
				Constructs a timed event loop that will be clocked at @c input_clock_rate.
			*/
			TimedEventLoop(unsigned int input_clock_rate);

			/*!
				Advances the event loop by @c number_of_cycles cycles.
			*/
			void run_for(const Cycles cycles);

			/*!
				@returns the number of whole cycles remaining until the next event is triggered.
			*/
			unsigned int get_cycles_until_next_event();

			/*!
				@returns the input clock rate.
			*/
			unsigned int get_input_clock_rate();

		protected:
			/*!
				Sets the time interval, as a proportion of a second, until the next event should be triggered.
			*/
			void set_next_event_time_interval(Time interval);

			/*!
				Communicates that the next event is triggered. A subclass will idiomatically process that event
				and make a fresh call to @c set_next_event_time_interval to keep the event loop running.
			*/
			virtual void process_next_event() = 0;

			/*!
				Optionally allows a subclass to track time within run_for periods; if a subclass implements
				advnace then it will receive advance increments that add up to the number of cycles supplied
				to run_for, but calls to process_next_event will be precisely interspersed. No time will carry
				forward between calls into run_for; a subclass can receive arbitrarily many instructions to
				advance before receiving a process_next_event.
			*/
			virtual void advance(const Cycles cycles) {};

			/*!
				Resets timing, throwing away any current internal state. So clears any fractional ticks
				that the event loop is currently tracking.
			*/
			void reset_timer();

			/*!
				Causes an immediate call to @c process_next_event and a call to @c reset_timer with the
				net effect of processing the current event immediately and fast forwarding exactly to the
				start of the interval prior to the next event.
			*/
			void jump_to_next_event();

			/*!
				@returns the amount of time that has passed since the last call to @c set_next_time_interval,
				which will always be less than or equal to the time that was supplied to @c set_next_time_interval.
			*/
			Time get_time_into_next_event();

		private:
			unsigned int input_clock_rate_;
			int cycles_until_event_;
			Time subcycles_until_event_;
	};

}

#endif /* TimedEventLoop_hpp */
<commit_msg>Corrects initial event loop timing state.<commit_after>//
//  TimedEventLoop.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 29/07/2016.
//  Copyright © 2016 Thomas Harte. All rights reserved.
//

#ifndef TimedEventLoop_hpp
#define TimedEventLoop_hpp

#include "Storage.hpp"
#include "../ClockReceiver/ClockReceiver.hpp"
#include "../SignalProcessing/Stepper.hpp"

#include <memory>

namespace Storage {

	/*!
		Provides a mechanism for arbitrarily timed events to be processed according to a fixed-base
		discrete clock signal, ensuring correct timing.

		Subclasses are responsible for calling @c set_next_event_time_interval to establish the time
		until a next event; @c process_next_event will be called when that event occurs, with progression
		determined via @c run_for.

		Due to the aggregation of total timing information between events — e.g. if an event loop has
		a clock rate of 1000 ticks per second and a steady stream of events that occur 10,000 times a second,
		bookkeeping is necessary to ensure that 10 events are triggered per tick — subclasses should call
		@c reset_timer if there is a discontinuity in events.

		Subclasses may also call @c jump_to_next_event to cause the next event to be communicated instantly.

		Subclasses are therefore expected to call @c set_next_event_time_interval upon obtaining an event stream,
		and again in response to each call to @c process_next_event while events are ongoing. They may use
		@c reset_timer to initiate a distinctly-timed stream or @c jump_to_next_event to short-circuit the timing
		loop and fast forward immediately to the next event.
	*/
	class TimedEventLoop {
		public:
			/*!
				Constructs a timed event loop that will be clocked at @c input_clock_rate.
			*/
			TimedEventLoop(unsigned int input_clock_rate);

			/*!
				Advances the event loop by @c number_of_cycles cycles.
			*/
			void run_for(const Cycles cycles);

			/*!
				@returns the number of whole cycles remaining until the next event is triggered.
			*/
			unsigned int get_cycles_until_next_event();

			/*!
				@returns the input clock rate.
			*/
			unsigned int get_input_clock_rate();

		protected:
			/*!
				Sets the time interval, as a proportion of a second, until the next event should be triggered.
			*/
			void set_next_event_time_interval(Time interval);

			/*!
				Communicates that the next event is triggered. A subclass will idiomatically process that event
				and make a fresh call to @c set_next_event_time_interval to keep the event loop running.
			*/
			virtual void process_next_event() = 0;

			/*!
				Optionally allows a subclass to track time within run_for periods; if a subclass implements
				advnace then it will receive advance increments that add up to the number of cycles supplied
				to run_for, but calls to process_next_event will be precisely interspersed. No time will carry
				forward between calls into run_for; a subclass can receive arbitrarily many instructions to
				advance before receiving a process_next_event.
			*/
			virtual void advance(const Cycles cycles) {};

			/*!
				Resets timing, throwing away any current internal state. So clears any fractional ticks
				that the event loop is currently tracking.
			*/
			void reset_timer();

			/*!
				Causes an immediate call to @c process_next_event and a call to @c reset_timer with the
				net effect of processing the current event immediately and fast forwarding exactly to the
				start of the interval prior to the next event.
			*/
			void jump_to_next_event();

			/*!
				@returns the amount of time that has passed since the last call to @c set_next_time_interval,
				which will always be less than or equal to the time that was supplied to @c set_next_time_interval.
			*/
			Time get_time_into_next_event();

		private:
			unsigned int input_clock_rate_ = 0;
			int cycles_until_event_ = 0;
			Time subcycles_until_event_;
	};

}

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


<commit_before>#include <bts/witness/witness.hpp>

#include <bts/chain/time.hpp>

#include <fc/thread/thread.hpp>

using namespace bts::witness_plugin;

void witness_plugin::configure(const bts::witness_plugin::witness_plugin::plugin_config& cfg)
{ try {
   _config = cfg;
} FC_CAPTURE_AND_RETHROW() }

void witness_plugin::init()
{ try {
   if( !_config.witness_keys.empty() )
      schedule_next_production(database().get_global_properties().parameters);
   else
      elog("No witnesses configured! Please add delegate IDs and private keys to configuration.");
   _production_enabled = _config.allow_production_on_stale_chain;
} FC_CAPTURE_AND_RETHROW() }

void witness_plugin::schedule_next_production(const bts::chain::chain_parameters& global_parameters)
{
   //Get next production time for *any* delegate
   auto block_interval = global_parameters.block_interval;
   fc::time_point next_block_time = fc::time_point_sec() +
         (chain::now().sec_since_epoch() / block_interval + 1) * block_interval;

   if( chain::ntp_time().valid() )
      next_block_time -= chain::ntp_error();

   //Sleep until the next production time for *any* delegate
   _block_production_task = fc::schedule([this]{block_production_loop();},
                                         next_block_time, "Witness Block Production");
}

void witness_plugin::block_production_loop()
{
   chain::database& db = database();
   std::set<chain::witness_id_type> witnesses;
   const auto& global_parameters = db.get_global_properties().parameters;

   // Is there a head block within a block interval of now? If so, we're synced and can begin production.
   if( !_production_enabled &&
       llabs((db.head_block_time() - chain::now()).to_seconds()) <= global_parameters.block_interval )
      _production_enabled = true;
   idump((_production_enabled));

   std::transform(_config.witness_keys.begin(), _config.witness_keys.end(),
                  std::inserter(witnesses, witnesses.begin()),
                  [](const std::pair<chain::witness_id_type,fc::ecc::private_key>& pair) {
                     return pair.first;
                  });

   auto next_production = db.get_next_generation_time(witnesses);
   wdump((next_production)(chain::now()));
   if( _production_enabled &&
       (llabs((next_production.first - chain::now()).count()) <= fc::seconds(1).count() || db.head_block_num() == 0) )
   {
      ilog("Witness ${id} production slot has arrived; generating a block now...", ("id", next_production.second));
      try {
         auto block = db.generate_block(_config.witness_keys[next_production.second], next_production.second);
         ilog("Generated block #${n} with timestamp ${t} at time ${c}",
              ("n", block.block_num())("t", block.timestamp)("c", chain::now()));
         p2p_node().broadcast(net::block_message(block));
      } catch( const fc::canceled_exception& ) {
         //We're trying to exit. Go ahead and let this one out.
         throw;
      } catch( const fc::exception& e ) {
         elog("Got exception while generating block:\n${e}", ("e", e.to_detail_string()));
      }
   }

   schedule_next_production(global_parameters);
}
<commit_msg>Resolve #18 Until further notice<commit_after>#include <bts/witness/witness.hpp>

#include <bts/chain/time.hpp>

#include <fc/thread/thread.hpp>

using namespace bts::witness_plugin;

void witness_plugin::configure(const bts::witness_plugin::witness_plugin::plugin_config& cfg)
{ try {
   _config = cfg;
} FC_CAPTURE_AND_RETHROW() }

void witness_plugin::init()
{ try {
   if( !_config.witness_keys.empty() )
      schedule_next_production(database().get_global_properties().parameters);
   else
      elog("No witnesses configured! Please add delegate IDs and private keys to configuration.");
   _production_enabled = _config.allow_production_on_stale_chain;
} FC_CAPTURE_AND_RETHROW() }

void witness_plugin::schedule_next_production(const bts::chain::chain_parameters& global_parameters)
{
   //Get next production time for *any* delegate
   auto block_interval = global_parameters.block_interval;
   fc::time_point next_block_time = fc::time_point_sec() +
         (chain::now().sec_since_epoch() / block_interval + 1) * block_interval;

   if( chain::ntp_time().valid() )
      next_block_time -= chain::ntp_error();

   //Sleep until the next production time for *any* delegate
   _block_production_task = fc::schedule([this]{block_production_loop();},
                                         next_block_time, "Witness Block Production");
}

void witness_plugin::block_production_loop()
{
   chain::database& db = database();
   std::set<chain::witness_id_type> witnesses;
   const auto& global_parameters = db.get_global_properties().parameters;

   // Is there a head block within a block interval of now? If so, we're synced and can begin production.
   if( !_production_enabled &&
       llabs((db.head_block_time() - chain::now()).to_seconds()) <= global_parameters.block_interval )
      _production_enabled = true;
   idump((_production_enabled));

   std::transform(_config.witness_keys.begin(), _config.witness_keys.end(),
                  std::inserter(witnesses, witnesses.begin()),
                  [](const std::pair<chain::witness_id_type,fc::ecc::private_key>& pair) {
                     return pair.first;
                  });

   auto next_production = db.get_next_generation_time(witnesses);
   wdump((next_production)(chain::now()));
   if( _production_enabled &&
       (llabs((next_production.first - chain::now()).count()) <= fc::milliseconds(500).count() || db.head_block_num() == 0) &&
       (chain::now() - db.head_block_time()).to_seconds() >= 1 )
   {
      ilog("Witness ${id} production slot has arrived; generating a block now...", ("id", next_production.second));
      try {
         auto block = db.generate_block(_config.witness_keys[next_production.second], next_production.second);
         ilog("Generated block #${n} with timestamp ${t} at time ${c}",
              ("n", block.block_num())("t", block.timestamp)("c", chain::now()));
         p2p_node().broadcast(net::block_message(block));
      } catch( const fc::canceled_exception& ) {
         //We're trying to exit. Go ahead and let this one out.
         throw;
      } catch( const fc::exception& e ) {
         elog("Got exception while generating block:\n${e}", ("e", e.to_detail_string()));
      }
   }

   schedule_next_production(global_parameters);
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// StochasticTools includes
#include "SamplerFullSolveMultiApp.h"
#include "Sampler.h"
#include "StochasticToolsTransfer.h"

registerMooseObject("StochasticToolsApp", SamplerFullSolveMultiApp);

InputParameters
SamplerFullSolveMultiApp::validParams()
{
  InputParameters params = FullSolveMultiApp::validParams();
  params += SamplerInterface::validParams();
  params += ReporterInterface::validParams();
  params.addClassDescription(
      "Creates a full-solve type sub-application for each row of each Sampler matrix.");
  params.addRequiredParam<SamplerName>("sampler",
                                       "The Sampler object to utilize for creating MultiApps.");
  params.suppressParameter<std::vector<Point>>("positions");
  params.suppressParameter<bool>("output_in_position");
  params.suppressParameter<std::vector<FileName>>("positions_file");
  params.suppressParameter<Real>("move_time");
  params.suppressParameter<std::vector<Point>>("move_positions");
  params.suppressParameter<std::vector<unsigned int>>("move_apps");
  params.set<bool>("use_positions") = false;

  MooseEnum modes("normal=0 batch-reset=1 batch-restore=2", "normal");
  params.addParam<MooseEnum>(
      "mode",
      modes,
      "The operation mode, 'normal' creates one sub-application for each row in the Sampler and "
      "'batch' creates one sub-application for each processor and re-executes for each row.");
  params.addParam<ReporterName>(
      "should_run_reporter",
      "Vector reporter value determining whether a certain multiapp should be run with this "
      "multiapp. This only works in batch-reset or batch-restore mode.");
  return params;
}

SamplerFullSolveMultiApp::SamplerFullSolveMultiApp(const InputParameters & parameters)
  : FullSolveMultiApp(parameters),
    SamplerInterface(this),
    ReporterInterface(this),
    _sampler(getSampler("sampler")),
    _mode(getParam<MooseEnum>("mode").getEnum<StochasticTools::MultiAppMode>()),
    _local_batch_app_index(0),
    _solved_once(false)
{
  if (getParam<unsigned int>("min_procs_per_app") !=
          _sampler.getParam<unsigned int>("min_procs_per_row") ||
      getParam<unsigned int>("max_procs_per_app") !=
          _sampler.getParam<unsigned int>("max_procs_per_row"))
    paramError("sampler",
               "Sampler and multiapp communicator configuration inconsistent. Please ensure that "
               "'MultiApps/",
               name(),
               "/min(max)_procs_per_app' and 'Samplers/",
               _sampler.name(),
               "/min(max)_procs_per_row' are the same.");

  init(_sampler.getNumberOfRows(),
       _sampler.getRankConfig(_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
                              _mode == StochasticTools::MultiAppMode::BATCH_RESTORE));
  _number_of_sampler_rows = _sampler.getNumberOfRows();

  if (isParamValid("should_run_reporter") && _mode == StochasticTools::MultiAppMode::NORMAL)
    paramError("should_run_reporter",
               "Conditionally run sampler multiapp only works in batch modes.");
}

void SamplerFullSolveMultiApp::preTransfer(Real /*dt*/, Real /*target_time*/)
{
  // Reinitialize MultiApp size
  const auto num_rows = _sampler.getNumberOfRows();
  if (num_rows != _number_of_sampler_rows)
  {
    init(num_rows,
         _sampler.getRankConfig(_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
                                _mode == StochasticTools::MultiAppMode::BATCH_RESTORE));
    _number_of_sampler_rows = num_rows;
    _row_data.clear();
  }

  // Reinitialize app to original state prior to solve, if a solve has occured
  if (_solved_once)
    initialSetup();

  if (isParamValid("should_run_reporter"))
    _should_run = &getReporterValue<std::vector<bool>>("should_run_reporter");
}

bool
SamplerFullSolveMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION("solveStep", 3, "Solving SamplerFullSolveMultiApp");

  mooseAssert(_my_num_apps, _sampler.getNumberOfLocalRows());

  bool last_solve_converged = true;

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
      _mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    last_solve_converged = solveStepBatch(dt, target_time, auto_advance);
  else
    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

  _solved_once = true;

  return last_solve_converged;
}

bool
SamplerFullSolveMultiApp::solveStepBatch(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION("solveStepBatch", 3, "Solving Step Batch For SamplerFullSolveMultiApp");

  if (_should_run && _should_run->size() < _sampler.getNumberOfLocalRows())
    paramError("should_run_reporter",
               "Reporter deteriming multiapp run must be of size greater than or equal to the "
               "number of local rows in the sampler, ",
               _should_run->size(),
               " < ",
               _sampler.getNumberOfLocalRows(),
               ".");

  // Value to return
  bool last_solve_converged = true;

  // List of active relevant Transfer objects
  std::vector<std::shared_ptr<StochasticToolsTransfer>> to_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::TO_MULTIAPP);
  std::vector<std::shared_ptr<StochasticToolsTransfer>> from_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::FROM_MULTIAPP);

  // Initialize to/from transfers
  for (auto transfer : to_transfers)
  {
    transfer->setGlobalMultiAppIndex(_rank_config.first_local_app_index);
    transfer->initializeToMultiapp();
  }
  for (auto transfer : from_transfers)
  {
    transfer->setGlobalMultiAppIndex(_rank_config.first_local_app_index);
    transfer->initializeFromMultiapp();
  }

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    backup();

  // Perform batch MultiApp solves
  _local_batch_app_index = 0;
  for (dof_id_type i = _rank_config.first_local_sim_index;
       i < _rank_config.first_local_sim_index + _rank_config.num_local_sims;
       ++i)
  {
    updateRowData(_local_batch_app_index);

    bool run = true;
    if (_should_run)
    {
      if (isRootProcessor())
        run = (*_should_run)[_local_batch_app_index];
      _my_communicator.broadcast(run, 0);
    }
    if (!run)
    {
      _local_batch_app_index++;
      continue;
    }

    for (auto & transfer : to_transfers)
    {
      transfer->setGlobalRowIndex(i);
      transfer->setCurrentRow(_row_data);
      transfer->executeToMultiapp();
    }

    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

    for (auto & transfer : from_transfers)
    {
      transfer->setGlobalRowIndex(i);
      transfer->setCurrentRow(_row_data);
      transfer->executeFromMultiapp();
    }

    _local_batch_app_index++;

    if (i < _rank_config.first_local_sim_index + _rank_config.num_local_sims - 1)
    {
      if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
        restore();
      else
      {
        resetApp(_local_batch_app_index + i, target_time);
        initialSetup();
      }
    }
  }
  _local_batch_app_index = 0;

  // Finalize to/from transfers
  for (auto transfer : to_transfers)
    transfer->finalizeToMultiapp();
  for (auto transfer : from_transfers)
    transfer->finalizeFromMultiapp();

  return last_solve_converged;
}

std::vector<std::shared_ptr<StochasticToolsTransfer>>
SamplerFullSolveMultiApp::getActiveStochasticToolsTransfers(Transfer::DIRECTION direction)
{
  std::vector<std::shared_ptr<StochasticToolsTransfer>> output;
  const ExecuteMooseObjectWarehouse<Transfer> & warehouse =
      _fe_problem.getMultiAppTransferWarehouse(direction);
  for (std::shared_ptr<Transfer> transfer : warehouse.getActiveObjects())
  {
    auto ptr = std::dynamic_pointer_cast<StochasticToolsTransfer>(transfer);
    if (ptr && ptr->getMultiApp().get() == this)
      output.push_back(ptr);
  }
  return output;
}

std::string
SamplerFullSolveMultiApp::getCommandLineArgsParamHelper(unsigned int local_app)
{
  std::string args;

  // With multiple processors per app, there are no local rows for non-root processors
  if (isRootProcessor())
  {
    // Since we only store param_names in cli_args, we need to find the values for each param from
    // sampler data and combine them to get full command line option strings.
    updateRowData(_mode == StochasticTools::MultiAppMode::NORMAL ? local_app
                                                                 : _local_batch_app_index);
    const std::vector<std::string> & full_args_name =
        MooseUtils::split(FullSolveMultiApp::getCommandLineArgsParamHelper(local_app), ";");
    args = sampledCommandLineArgs(_row_data, full_args_name);
  }

  _my_communicator.broadcast(args);
  return args;
}

void
SamplerFullSolveMultiApp::updateRowData(dof_id_type local_index)
{
  if (!isRootProcessor())
    return;

  mooseAssert(local_index < _sampler.getNumberOfLocalRows(),
              "Local index must be less than number of local rows.");

  if (_row_data.empty() ||
      (_local_row_index == _sampler.getNumberOfLocalRows() - 1 && local_index == 0))
  {
    mooseAssert(local_index == 0,
                "The first time calling updateRowData must have a local index of 0.");
    _local_row_index = 0;
    _row_data = _sampler.getNextLocalRow();
  }
  else if (local_index - _local_row_index == 1)
  {
    _local_row_index++;
    _row_data = _sampler.getNextLocalRow();
  }

  mooseAssert(local_index == _local_row_index,
              "Local index must be equal or one greater than the index previously called.");
}

std::string
SamplerFullSolveMultiApp::sampledCommandLineArgs(const std::vector<Real> & row,
                                                 const std::vector<std::string> & full_args_name)
{
  std::ostringstream oss;

  // Find parameters that are meant to be assigned by sampler values
  std::vector<std::string> cli_args_name;
  for (const auto & fan : full_args_name)
  {
    // If it has an '=', then it is not meant to be modified
    if (fan.find("=") == std::string::npos)
      cli_args_name.push_back(fan);
    else
      oss << fan << ";";
  }

  // Make sure the parameters either all have brackets, or none of them do
  bool has_brackets = false;
  if (cli_args_name.size())
  {
    has_brackets = cli_args_name[0].find("[") != std::string::npos;
    for (unsigned int i = 1; i < cli_args_name.size(); ++i)
      if (has_brackets != (cli_args_name[i].find("[") != std::string::npos))
        ::mooseError("If the bracket is used, it must be provided to every parameter.");
  }
  if (!has_brackets && cli_args_name.size() && cli_args_name.size() != row.size())
    ::mooseError("Number of command line arguments does not match number of sampler columns.");

  for (unsigned int i = 0; i < cli_args_name.size(); ++i)
  {
    // Assign bracketed parameters
    if (has_brackets)
    {
      // Split param name and vector assignment: "param[0,(3.14),1]" -> {"param", "0,(3.14),1]"}
      const std::vector<std::string> & vector_param = MooseUtils::split(cli_args_name[i], "[");
      // Get inices of vector: "0,(3.14),1]" -> {"0", "(3.14)", "1"}
      const std::vector<std::string> & index_string =
          MooseUtils::split(vector_param[1].substr(0, vector_param[1].find("]")), ",");

      // Loop through indices and assign parameter: param='row[0] 3.14 row[1]'
      oss << vector_param[0] << "='";
      std::string sep = "";
      for (const auto & istr : index_string)
      {
        oss << sep;
        sep = " ";
        // If the value is enclosed in parentheses, then it isn't an index, it's a value
        if (istr.find("(") != std::string::npos)
          oss << std::stod(istr.substr(istr.find("(") + 1));
        // Assign the value from row if it is an index
        else
        {
          unsigned int index = MooseUtils::stringToInteger(istr);
          if (index >= row.size())
            ::mooseError("The provided global column index (",
                         index,
                         ") for ",
                         vector_param[0],
                         " is out of bound.");
          oss << Moose::stringify(row[index]);
        }
      }
      oss << "';";
    }
    // Assign scalar parameters
    else
    {
      oss << cli_args_name[i] << "=" << Moose::stringify(row[i]) << ";";
    }
  }

  return oss.str();
}
<commit_msg>Move initalSetup for batch-reset to the front. (#21438)<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

// StochasticTools includes
#include "SamplerFullSolveMultiApp.h"
#include "Sampler.h"
#include "StochasticToolsTransfer.h"

registerMooseObject("StochasticToolsApp", SamplerFullSolveMultiApp);

InputParameters
SamplerFullSolveMultiApp::validParams()
{
  InputParameters params = FullSolveMultiApp::validParams();
  params += SamplerInterface::validParams();
  params += ReporterInterface::validParams();
  params.addClassDescription(
      "Creates a full-solve type sub-application for each row of each Sampler matrix.");
  params.addRequiredParam<SamplerName>("sampler",
                                       "The Sampler object to utilize for creating MultiApps.");
  params.suppressParameter<std::vector<Point>>("positions");
  params.suppressParameter<bool>("output_in_position");
  params.suppressParameter<std::vector<FileName>>("positions_file");
  params.suppressParameter<Real>("move_time");
  params.suppressParameter<std::vector<Point>>("move_positions");
  params.suppressParameter<std::vector<unsigned int>>("move_apps");
  params.set<bool>("use_positions") = false;

  MooseEnum modes("normal=0 batch-reset=1 batch-restore=2", "normal");
  params.addParam<MooseEnum>(
      "mode",
      modes,
      "The operation mode, 'normal' creates one sub-application for each row in the Sampler and "
      "'batch' creates one sub-application for each processor and re-executes for each row.");
  params.addParam<ReporterName>(
      "should_run_reporter",
      "Vector reporter value determining whether a certain multiapp should be run with this "
      "multiapp. This only works in batch-reset or batch-restore mode.");
  return params;
}

SamplerFullSolveMultiApp::SamplerFullSolveMultiApp(const InputParameters & parameters)
  : FullSolveMultiApp(parameters),
    SamplerInterface(this),
    ReporterInterface(this),
    _sampler(getSampler("sampler")),
    _mode(getParam<MooseEnum>("mode").getEnum<StochasticTools::MultiAppMode>()),
    _local_batch_app_index(0),
    _solved_once(false)
{
  if (getParam<unsigned int>("min_procs_per_app") !=
          _sampler.getParam<unsigned int>("min_procs_per_row") ||
      getParam<unsigned int>("max_procs_per_app") !=
          _sampler.getParam<unsigned int>("max_procs_per_row"))
    paramError("sampler",
               "Sampler and multiapp communicator configuration inconsistent. Please ensure that "
               "'MultiApps/",
               name(),
               "/min(max)_procs_per_app' and 'Samplers/",
               _sampler.name(),
               "/min(max)_procs_per_row' are the same.");

  init(_sampler.getNumberOfRows(),
       _sampler.getRankConfig(_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
                              _mode == StochasticTools::MultiAppMode::BATCH_RESTORE));
  _number_of_sampler_rows = _sampler.getNumberOfRows();

  if (isParamValid("should_run_reporter") && _mode == StochasticTools::MultiAppMode::NORMAL)
    paramError("should_run_reporter",
               "Conditionally run sampler multiapp only works in batch modes.");
}

void
SamplerFullSolveMultiApp::preTransfer(Real /*dt*/, Real /*target_time*/)
{
  // Reinitialize MultiApp size
  const auto num_rows = _sampler.getNumberOfRows();
  if (num_rows != _number_of_sampler_rows)
  {
    init(num_rows,
         _sampler.getRankConfig(_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
                                _mode == StochasticTools::MultiAppMode::BATCH_RESTORE));
    _number_of_sampler_rows = num_rows;
    _row_data.clear();
  }

  // Reinitialize app to original state prior to solve, if a solve has occured
  if (_solved_once && (_mode == StochasticTools::MultiAppMode::NORMAL ||
                       _mode == StochasticTools::MultiAppMode::BATCH_RESTORE))
    initialSetup();

  if (isParamValid("should_run_reporter"))
    _should_run = &getReporterValue<std::vector<bool>>("should_run_reporter");
}

bool
SamplerFullSolveMultiApp::solveStep(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION("solveStep", 3, "Solving SamplerFullSolveMultiApp");

  mooseAssert(_my_num_apps, _sampler.getNumberOfLocalRows());

  bool last_solve_converged = true;

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESET ||
      _mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    last_solve_converged = solveStepBatch(dt, target_time, auto_advance);
  else
    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

  _solved_once = true;

  return last_solve_converged;
}

bool
SamplerFullSolveMultiApp::solveStepBatch(Real dt, Real target_time, bool auto_advance)
{
  TIME_SECTION("solveStepBatch", 3, "Solving Step Batch For SamplerFullSolveMultiApp");

  if (_should_run && _should_run->size() < _sampler.getNumberOfLocalRows())
    paramError("should_run_reporter",
               "Reporter deteriming multiapp run must be of size greater than or equal to the "
               "number of local rows in the sampler, ",
               _should_run->size(),
               " < ",
               _sampler.getNumberOfLocalRows(),
               ".");

  // Value to return
  bool last_solve_converged = true;

  // List of active relevant Transfer objects
  std::vector<std::shared_ptr<StochasticToolsTransfer>> to_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::TO_MULTIAPP);
  std::vector<std::shared_ptr<StochasticToolsTransfer>> from_transfers =
      getActiveStochasticToolsTransfers(MultiAppTransfer::FROM_MULTIAPP);

  // Initialize to/from transfers
  for (auto transfer : to_transfers)
  {
    transfer->setGlobalMultiAppIndex(_rank_config.first_local_app_index);
    transfer->initializeToMultiapp();
  }
  for (auto transfer : from_transfers)
  {
    transfer->setGlobalMultiAppIndex(_rank_config.first_local_app_index);
    transfer->initializeFromMultiapp();
  }

  if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
    backup();

  // Perform batch MultiApp solves
  _local_batch_app_index = 0;
  for (dof_id_type i = _rank_config.first_local_sim_index;
       i < _rank_config.first_local_sim_index + _rank_config.num_local_sims;
       ++i)
  {
    updateRowData(_local_batch_app_index);

    bool run = true;
    if (_should_run)
    {
      if (isRootProcessor())
        run = (*_should_run)[_local_batch_app_index];
      _my_communicator.broadcast(run, 0);
    }
    if (!run)
    {
      _local_batch_app_index++;
      continue;
    }

    if (_mode == StochasticTools::MultiAppMode::BATCH_RESTORE)
      restore();
    else
      initialSetup();

    for (auto & transfer : to_transfers)
    {
      transfer->setGlobalRowIndex(i);
      transfer->setCurrentRow(_row_data);
      transfer->executeToMultiapp();
    }

    last_solve_converged = FullSolveMultiApp::solveStep(dt, target_time, auto_advance);

    for (auto & transfer : from_transfers)
    {
      transfer->setGlobalRowIndex(i);
      transfer->setCurrentRow(_row_data);
      transfer->executeFromMultiapp();
    }

    _local_batch_app_index++;
  }
  _local_batch_app_index = 0;

  // Finalize to/from transfers
  for (auto transfer : to_transfers)
    transfer->finalizeToMultiapp();
  for (auto transfer : from_transfers)
    transfer->finalizeFromMultiapp();

  return last_solve_converged;
}

std::vector<std::shared_ptr<StochasticToolsTransfer>>
SamplerFullSolveMultiApp::getActiveStochasticToolsTransfers(Transfer::DIRECTION direction)
{
  std::vector<std::shared_ptr<StochasticToolsTransfer>> output;
  const ExecuteMooseObjectWarehouse<Transfer> & warehouse =
      _fe_problem.getMultiAppTransferWarehouse(direction);
  for (std::shared_ptr<Transfer> transfer : warehouse.getActiveObjects())
  {
    auto ptr = std::dynamic_pointer_cast<StochasticToolsTransfer>(transfer);
    if (ptr && ptr->getMultiApp().get() == this)
      output.push_back(ptr);
  }
  return output;
}

std::string
SamplerFullSolveMultiApp::getCommandLineArgsParamHelper(unsigned int local_app)
{
  std::string args;

  // With multiple processors per app, there are no local rows for non-root processors
  if (isRootProcessor())
  {
    // We only request a new parameter sample if we are in normal mode, otherwise this is
    // taken care of the batchSolve
    updateRowData(_mode == StochasticTools::MultiAppMode::NORMAL ? local_app
                                                                 : _local_batch_app_index);

    // Since we only store param_names in cli_args, we need to find the values for each param from
    // sampler data and combine them to get full command line option strings.
    const std::vector<std::string> & full_args_name =
        MooseUtils::split(FullSolveMultiApp::getCommandLineArgsParamHelper(local_app), ";");
    args = sampledCommandLineArgs(_row_data, full_args_name);
  }

  _my_communicator.broadcast(args);
  return args;
}

void
SamplerFullSolveMultiApp::updateRowData(dof_id_type local_index)
{
  if (!isRootProcessor())
    return;

  mooseAssert(local_index < _sampler.getNumberOfLocalRows(),
              "Local index must be less than number of local rows.");

  if (_row_data.empty() ||
      (_local_row_index == _sampler.getNumberOfLocalRows() - 1 && local_index == 0))
  {
    mooseAssert(local_index == 0,
                "The first time calling updateRowData must have a local index of 0.");
    _local_row_index = 0;
    _row_data = _sampler.getNextLocalRow();
  }
  else if (local_index - _local_row_index == 1)
  {
    _local_row_index++;
    _row_data = _sampler.getNextLocalRow();
  }

  mooseAssert(local_index == _local_row_index,
              "Local index must be equal or one greater than the index previously called.");
}

std::string
SamplerFullSolveMultiApp::sampledCommandLineArgs(const std::vector<Real> & row,
                                                 const std::vector<std::string> & full_args_name)
{
  std::ostringstream oss;

  // Find parameters that are meant to be assigned by sampler values
  std::vector<std::string> cli_args_name;
  for (const auto & fan : full_args_name)
  {
    // If it has an '=', then it is not meant to be modified
    if (fan.find("=") == std::string::npos)
      cli_args_name.push_back(fan);
    else
      oss << fan << ";";
  }

  // Make sure the parameters either all have brackets, or none of them do
  bool has_brackets = false;
  if (cli_args_name.size())
  {
    has_brackets = cli_args_name[0].find("[") != std::string::npos;
    for (unsigned int i = 1; i < cli_args_name.size(); ++i)
      if (has_brackets != (cli_args_name[i].find("[") != std::string::npos))
        ::mooseError("If the bracket is used, it must be provided to every parameter.");
  }
  if (!has_brackets && cli_args_name.size() && cli_args_name.size() != row.size())
    ::mooseError("Number of command line arguments does not match number of sampler columns.");

  for (unsigned int i = 0; i < cli_args_name.size(); ++i)
  {
    // Assign bracketed parameters
    if (has_brackets)
    {
      // Split param name and vector assignment: "param[0,(3.14),1]" -> {"param", "0,(3.14),1]"}
      const std::vector<std::string> & vector_param = MooseUtils::split(cli_args_name[i], "[");
      // Get inices of vector: "0,(3.14),1]" -> {"0", "(3.14)", "1"}
      const std::vector<std::string> & index_string =
          MooseUtils::split(vector_param[1].substr(0, vector_param[1].find("]")), ",");

      // Loop through indices and assign parameter: param='row[0] 3.14 row[1]'
      oss << vector_param[0] << "='";
      std::string sep = "";
      for (const auto & istr : index_string)
      {
        oss << sep;
        sep = " ";
        // If the value is enclosed in parentheses, then it isn't an index, it's a value
        if (istr.find("(") != std::string::npos)
          oss << std::stod(istr.substr(istr.find("(") + 1));
        // Assign the value from row if it is an index
        else
        {
          unsigned int index = MooseUtils::stringToInteger(istr);
          if (index >= row.size())
            ::mooseError("The provided global column index (",
                         index,
                         ") for ",
                         vector_param[0],
                         " is out of bound.");
          oss << Moose::stringify(row[index]);
        }
      }
      oss << "';";
    }
    // Assign scalar parameters
    else
    {
      oss << cli_args_name[i] << "=" << Moose::stringify(row[i]) << ";";
    }
  }

  return oss.str();
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <string>

#include "chrome/browser/download/download_extensions.h"

#include "base/string_util.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"

namespace download_util {

// For file extensions taken from mozilla:

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Mozilla Communicator client code, released
 * March 31, 1998.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Doug Turner <dougt@netscape.com>
 *   Dean Tessman <dean_tessman@hotmail.com>
 *   Brodie Thiesfield <brofield@jellycan.com>
 *   Jungshik Shin <jshin@i18nl10n.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

static const struct Executables {
    const char* extension;
    DownloadDangerLevel level;
} g_executables[] = {
// Chrome OS does not suffer from some of the problems of older OS'es.
#if !defined(OS_CHROMEOS)
  // Relating to Java.
  { "class", DANGEROUS },
  { "jar", DANGEROUS },
  { "jnlp", DANGEROUS },
  // Relating to PDF.
  { "pdf", ALLOW_ON_USER_GESTURE },
  { "pdfxml", ALLOW_ON_USER_GESTURE },
  { "mars", ALLOW_ON_USER_GESTURE },
  { "fdf", ALLOW_ON_USER_GESTURE },
  { "xfdf", ALLOW_ON_USER_GESTURE },
  { "xdp", ALLOW_ON_USER_GESTURE },
  { "xfd", ALLOW_ON_USER_GESTURE },
  // Relating to scripting languages.
  { "pl", ALLOW_ON_USER_GESTURE },
  { "py", ALLOW_ON_USER_GESTURE },
  { "pyw", ALLOW_ON_USER_GESTURE },
  { "rb", ALLOW_ON_USER_GESTURE },
#endif
  // Some files are dangerous on all platforms.
  // Flash files downloaded locally can sometimes access the local filesystem.
  { "swf", ALLOW_ON_USER_GESTURE },
  // Chrome extensions should be obtained through the web store.
  { "crx", ALLOW_ON_USER_GESTURE },
  // These types can run JavaScript (e.g. HTML and HTML-like).
  // TODO(cevans): work out whether our restrictions on file:/// are strong
  // enough to mark these types as no longer dangerous.
  { "htm", ALLOW_ON_USER_GESTURE },
  { "html", ALLOW_ON_USER_GESTURE },
  { "shtm", ALLOW_ON_USER_GESTURE },
  { "shtml", ALLOW_ON_USER_GESTURE },
  { "svg", ALLOW_ON_USER_GESTURE },
  { "xht", ALLOW_ON_USER_GESTURE },
  { "xhtm", ALLOW_ON_USER_GESTURE },
  { "xhtml", ALLOW_ON_USER_GESTURE },
  { "xml", ALLOW_ON_USER_GESTURE },
  { "xsl", ALLOW_ON_USER_GESTURE },
  { "xslt", ALLOW_ON_USER_GESTURE },
#if defined(OS_WIN)
  { "ad", ALLOW_ON_USER_GESTURE },
  { "ade", ALLOW_ON_USER_GESTURE },
  { "adp", ALLOW_ON_USER_GESTURE },
  { "app", ALLOW_ON_USER_GESTURE },
  { "application", ALLOW_ON_USER_GESTURE },
  { "asp", ALLOW_ON_USER_GESTURE },
  { "asx", ALLOW_ON_USER_GESTURE },
  { "bas", ALLOW_ON_USER_GESTURE },
  { "bat", ALLOW_ON_USER_GESTURE },
  { "cfg", DANGEROUS },
  { "chi", ALLOW_ON_USER_GESTURE },
  { "chm", ALLOW_ON_USER_GESTURE },
  { "cmd", ALLOW_ON_USER_GESTURE },
  { "com", ALLOW_ON_USER_GESTURE },
  { "cpl", ALLOW_ON_USER_GESTURE },
  { "crt", ALLOW_ON_USER_GESTURE },
  { "dll", DANGEROUS },
  { "drv", DANGEROUS },
  { "exe", ALLOW_ON_USER_GESTURE },
  { "fxp", ALLOW_ON_USER_GESTURE },
  { "grp", DANGEROUS },
  { "hlp", ALLOW_ON_USER_GESTURE },
  { "hta", ALLOW_ON_USER_GESTURE },
  { "htt", ALLOW_ON_USER_GESTURE },
  { "inf", ALLOW_ON_USER_GESTURE },
  { "ini", DANGEROUS },
  { "ins", ALLOW_ON_USER_GESTURE },
  { "isp", ALLOW_ON_USER_GESTURE },
  { "js", ALLOW_ON_USER_GESTURE },
  { "jse", ALLOW_ON_USER_GESTURE },
  { "lnk", ALLOW_ON_USER_GESTURE },
  { "local", DANGEROUS },
  { "mad", ALLOW_ON_USER_GESTURE },
  { "maf", ALLOW_ON_USER_GESTURE },
  { "mag", ALLOW_ON_USER_GESTURE },
  { "mam", ALLOW_ON_USER_GESTURE },
  { "manifest", DANGEROUS },
  { "maq", ALLOW_ON_USER_GESTURE },
  { "mar", ALLOW_ON_USER_GESTURE },
  { "mas", ALLOW_ON_USER_GESTURE },
  { "mat", ALLOW_ON_USER_GESTURE },
  { "mau", ALLOW_ON_USER_GESTURE },
  { "mav", ALLOW_ON_USER_GESTURE },
  { "maw", ALLOW_ON_USER_GESTURE },
  { "mda", ALLOW_ON_USER_GESTURE },
  { "mdb", ALLOW_ON_USER_GESTURE },
  { "mde", ALLOW_ON_USER_GESTURE },
  { "mdt", ALLOW_ON_USER_GESTURE },
  { "mdw", ALLOW_ON_USER_GESTURE },
  { "mdz", ALLOW_ON_USER_GESTURE },
  { "mht", ALLOW_ON_USER_GESTURE },
  { "mhtml", ALLOW_ON_USER_GESTURE },
  { "mmc", ALLOW_ON_USER_GESTURE },
  { "mof", DANGEROUS },
  { "msc", ALLOW_ON_USER_GESTURE },
  { "msh", ALLOW_ON_USER_GESTURE },
  { "mshxml", ALLOW_ON_USER_GESTURE },
  { "msi", ALLOW_ON_USER_GESTURE },
  { "msp", ALLOW_ON_USER_GESTURE },
  { "mst", ALLOW_ON_USER_GESTURE },
  { "ocx", DANGEROUS },
  { "ops", ALLOW_ON_USER_GESTURE },
  { "pcd", ALLOW_ON_USER_GESTURE },
  { "pif", ALLOW_ON_USER_GESTURE },
  { "plg", ALLOW_ON_USER_GESTURE },
  { "prf", ALLOW_ON_USER_GESTURE },
  { "prg", ALLOW_ON_USER_GESTURE },
  { "pst", ALLOW_ON_USER_GESTURE },
  { "reg", ALLOW_ON_USER_GESTURE },
  { "scf", ALLOW_ON_USER_GESTURE },
  { "scr", ALLOW_ON_USER_GESTURE },
  { "sct", ALLOW_ON_USER_GESTURE },
  { "shb", ALLOW_ON_USER_GESTURE },
  { "shs", ALLOW_ON_USER_GESTURE },
  { "sys", DANGEROUS },
  { "url", ALLOW_ON_USER_GESTURE },
  // TODO(davidben): Remove this when double-extensions are no longer
  // a nuisance.
  { "user.js", ALLOW_ON_USER_GESTURE },
  { "vb", ALLOW_ON_USER_GESTURE },
  { "vbe", ALLOW_ON_USER_GESTURE },
  { "vbs", ALLOW_ON_USER_GESTURE },
  { "vsd", ALLOW_ON_USER_GESTURE },
  { "vsmacros", ALLOW_ON_USER_GESTURE },
  { "vss", ALLOW_ON_USER_GESTURE },
  { "vst", ALLOW_ON_USER_GESTURE },
  { "vsw", ALLOW_ON_USER_GESTURE },
  { "ws", ALLOW_ON_USER_GESTURE },
  { "wsc", ALLOW_ON_USER_GESTURE },
  { "wsf", ALLOW_ON_USER_GESTURE },
  { "wsh", ALLOW_ON_USER_GESTURE },
  { "xbap", DANGEROUS },
#elif defined(OS_MACOSX)
  { "bash", ALLOW_ON_USER_GESTURE },
  { "command", ALLOW_ON_USER_GESTURE },
  { "csh", ALLOW_ON_USER_GESTURE },
  { "ksh", ALLOW_ON_USER_GESTURE },
  { "pkg", ALLOW_ON_USER_GESTURE },
  { "sh", ALLOW_ON_USER_GESTURE },
  { "shar", ALLOW_ON_USER_GESTURE },
  { "tcsh", ALLOW_ON_USER_GESTURE },
#elif defined(OS_POSIX)
  // TODO(estade): lengthen this list.
  { "bash", ALLOW_ON_USER_GESTURE },
  { "csh", ALLOW_ON_USER_GESTURE },
  { "deb", ALLOW_ON_USER_GESTURE },
  { "exe", ALLOW_ON_USER_GESTURE },
  { "ksh", ALLOW_ON_USER_GESTURE },
  { "rpm", ALLOW_ON_USER_GESTURE },
  { "sh", ALLOW_ON_USER_GESTURE },
  { "shar", ALLOW_ON_USER_GESTURE },
  { "tcsh", ALLOW_ON_USER_GESTURE },
#elif defined(OS_ANDROID)
  { "apk", ALLOW_ON_USER_GESTURE },
  { "sh", ALLOW_ON_USER_GESTURE },
  { "shar", ALLOW_ON_USER_GESTURE },
  { "dex", ALLOW_ON_USER_GESTURE },
#endif
};

DownloadDangerLevel GetFileDangerLevel(const base::FilePath& path) {
  base::FilePath::StringType extension(path.Extension());
  if (extension.empty())
    return NOT_DANGEROUS;
  if (!IsStringASCII(extension))
    return NOT_DANGEROUS;
#if defined(OS_WIN)
  std::string ascii_extension = WideToASCII(extension);
#elif defined(OS_POSIX)
  std::string ascii_extension = extension;
#endif

  // Strip out leading dot if it's still there
  if (ascii_extension[0] == base::FilePath::kExtensionSeparator)
    ascii_extension.erase(0, 1);

  for (size_t i = 0; i < arraysize(g_executables); ++i) {
    if (LowerCaseEqualsASCII(ascii_extension, g_executables[i].extension))
      return g_executables[i].level;
  }
  return NOT_DANGEROUS;
}

static const char* kExecutableWhiteList[] = {
  // JavaScript is just as powerful as EXE.
  "text/javascript",
  "text/javascript;version=*",
  "text/html",
  // Registry files can cause critical changes to the MS OS behavior.
  // Addition of this mimetype also addresses bug 7337.
  "text/x-registry",
  "text/x-sh",
  // Some sites use binary/octet-stream to mean application/octet-stream.
  // See http://code.google.com/p/chromium/issues/detail?id=1573
  "binary/octet-stream"
};

static const char* kExecutableBlackList[] = {
  // These application types are not executable.
  "application/*+xml",
  "application/xml"
};

bool IsExecutableMimeType(const std::string& mime_type) {
  for (size_t i = 0; i < arraysize(kExecutableWhiteList); ++i) {
    if (net::MatchesMimeType(kExecutableWhiteList[i], mime_type))
      return true;
  }
  for (size_t i = 0; i < arraysize(kExecutableBlackList); ++i) {
    if (net::MatchesMimeType(kExecutableBlackList[i], mime_type))
      return false;
  }
  // We consider only other application types to be executable.
  return net::MatchesMimeType("application/*", mime_type);
}

}  // namespace download_util
<commit_msg>Check dangerous Android file extensions on authenticated download<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <set>
#include <string>

#include "chrome/browser/download/download_extensions.h"

#include "base/string_util.h"
#include "net/base/mime_util.h"
#include "net/base/net_util.h"

namespace download_util {

// For file extensions taken from mozilla:

/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is Mozilla Communicator client code, released
 * March 31, 1998.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998-1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Doug Turner <dougt@netscape.com>
 *   Dean Tessman <dean_tessman@hotmail.com>
 *   Brodie Thiesfield <brofield@jellycan.com>
 *   Jungshik Shin <jshin@i18nl10n.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

static const struct Executables {
    const char* extension;
    DownloadDangerLevel level;
} g_executables[] = {
// Chrome OS does not suffer from some of the problems of older OS'es.
#if !defined(OS_CHROMEOS)
  // Relating to Java.
  { "class", DANGEROUS },
  { "jar", DANGEROUS },
  { "jnlp", DANGEROUS },
  // Relating to PDF.
  { "pdf", ALLOW_ON_USER_GESTURE },
  { "pdfxml", ALLOW_ON_USER_GESTURE },
  { "mars", ALLOW_ON_USER_GESTURE },
  { "fdf", ALLOW_ON_USER_GESTURE },
  { "xfdf", ALLOW_ON_USER_GESTURE },
  { "xdp", ALLOW_ON_USER_GESTURE },
  { "xfd", ALLOW_ON_USER_GESTURE },
  // Relating to scripting languages.
  { "pl", ALLOW_ON_USER_GESTURE },
  { "py", ALLOW_ON_USER_GESTURE },
  { "pyw", ALLOW_ON_USER_GESTURE },
  { "rb", ALLOW_ON_USER_GESTURE },
#endif
  // Some files are dangerous on all platforms.
  // Flash files downloaded locally can sometimes access the local filesystem.
  { "swf", ALLOW_ON_USER_GESTURE },
  // Chrome extensions should be obtained through the web store.
  { "crx", ALLOW_ON_USER_GESTURE },
  // These types can run JavaScript (e.g. HTML and HTML-like).
  // TODO(cevans): work out whether our restrictions on file:/// are strong
  // enough to mark these types as no longer dangerous.
  { "htm", ALLOW_ON_USER_GESTURE },
  { "html", ALLOW_ON_USER_GESTURE },
  { "shtm", ALLOW_ON_USER_GESTURE },
  { "shtml", ALLOW_ON_USER_GESTURE },
  { "svg", ALLOW_ON_USER_GESTURE },
  { "xht", ALLOW_ON_USER_GESTURE },
  { "xhtm", ALLOW_ON_USER_GESTURE },
  { "xhtml", ALLOW_ON_USER_GESTURE },
  { "xml", ALLOW_ON_USER_GESTURE },
  { "xsl", ALLOW_ON_USER_GESTURE },
  { "xslt", ALLOW_ON_USER_GESTURE },
#if defined(OS_WIN)
  { "ad", ALLOW_ON_USER_GESTURE },
  { "ade", ALLOW_ON_USER_GESTURE },
  { "adp", ALLOW_ON_USER_GESTURE },
  { "app", ALLOW_ON_USER_GESTURE },
  { "application", ALLOW_ON_USER_GESTURE },
  { "asp", ALLOW_ON_USER_GESTURE },
  { "asx", ALLOW_ON_USER_GESTURE },
  { "bas", ALLOW_ON_USER_GESTURE },
  { "bat", ALLOW_ON_USER_GESTURE },
  { "cfg", DANGEROUS },
  { "chi", ALLOW_ON_USER_GESTURE },
  { "chm", ALLOW_ON_USER_GESTURE },
  { "cmd", ALLOW_ON_USER_GESTURE },
  { "com", ALLOW_ON_USER_GESTURE },
  { "cpl", ALLOW_ON_USER_GESTURE },
  { "crt", ALLOW_ON_USER_GESTURE },
  { "dll", DANGEROUS },
  { "drv", DANGEROUS },
  { "exe", ALLOW_ON_USER_GESTURE },
  { "fxp", ALLOW_ON_USER_GESTURE },
  { "grp", DANGEROUS },
  { "hlp", ALLOW_ON_USER_GESTURE },
  { "hta", ALLOW_ON_USER_GESTURE },
  { "htt", ALLOW_ON_USER_GESTURE },
  { "inf", ALLOW_ON_USER_GESTURE },
  { "ini", DANGEROUS },
  { "ins", ALLOW_ON_USER_GESTURE },
  { "isp", ALLOW_ON_USER_GESTURE },
  { "js", ALLOW_ON_USER_GESTURE },
  { "jse", ALLOW_ON_USER_GESTURE },
  { "lnk", ALLOW_ON_USER_GESTURE },
  { "local", DANGEROUS },
  { "mad", ALLOW_ON_USER_GESTURE },
  { "maf", ALLOW_ON_USER_GESTURE },
  { "mag", ALLOW_ON_USER_GESTURE },
  { "mam", ALLOW_ON_USER_GESTURE },
  { "manifest", DANGEROUS },
  { "maq", ALLOW_ON_USER_GESTURE },
  { "mar", ALLOW_ON_USER_GESTURE },
  { "mas", ALLOW_ON_USER_GESTURE },
  { "mat", ALLOW_ON_USER_GESTURE },
  { "mau", ALLOW_ON_USER_GESTURE },
  { "mav", ALLOW_ON_USER_GESTURE },
  { "maw", ALLOW_ON_USER_GESTURE },
  { "mda", ALLOW_ON_USER_GESTURE },
  { "mdb", ALLOW_ON_USER_GESTURE },
  { "mde", ALLOW_ON_USER_GESTURE },
  { "mdt", ALLOW_ON_USER_GESTURE },
  { "mdw", ALLOW_ON_USER_GESTURE },
  { "mdz", ALLOW_ON_USER_GESTURE },
  { "mht", ALLOW_ON_USER_GESTURE },
  { "mhtml", ALLOW_ON_USER_GESTURE },
  { "mmc", ALLOW_ON_USER_GESTURE },
  { "mof", DANGEROUS },
  { "msc", ALLOW_ON_USER_GESTURE },
  { "msh", ALLOW_ON_USER_GESTURE },
  { "mshxml", ALLOW_ON_USER_GESTURE },
  { "msi", ALLOW_ON_USER_GESTURE },
  { "msp", ALLOW_ON_USER_GESTURE },
  { "mst", ALLOW_ON_USER_GESTURE },
  { "ocx", DANGEROUS },
  { "ops", ALLOW_ON_USER_GESTURE },
  { "pcd", ALLOW_ON_USER_GESTURE },
  { "pif", ALLOW_ON_USER_GESTURE },
  { "plg", ALLOW_ON_USER_GESTURE },
  { "prf", ALLOW_ON_USER_GESTURE },
  { "prg", ALLOW_ON_USER_GESTURE },
  { "pst", ALLOW_ON_USER_GESTURE },
  { "reg", ALLOW_ON_USER_GESTURE },
  { "scf", ALLOW_ON_USER_GESTURE },
  { "scr", ALLOW_ON_USER_GESTURE },
  { "sct", ALLOW_ON_USER_GESTURE },
  { "shb", ALLOW_ON_USER_GESTURE },
  { "shs", ALLOW_ON_USER_GESTURE },
  { "sys", DANGEROUS },
  { "url", ALLOW_ON_USER_GESTURE },
  // TODO(davidben): Remove this when double-extensions are no longer
  // a nuisance.
  { "user.js", ALLOW_ON_USER_GESTURE },
  { "vb", ALLOW_ON_USER_GESTURE },
  { "vbe", ALLOW_ON_USER_GESTURE },
  { "vbs", ALLOW_ON_USER_GESTURE },
  { "vsd", ALLOW_ON_USER_GESTURE },
  { "vsmacros", ALLOW_ON_USER_GESTURE },
  { "vss", ALLOW_ON_USER_GESTURE },
  { "vst", ALLOW_ON_USER_GESTURE },
  { "vsw", ALLOW_ON_USER_GESTURE },
  { "ws", ALLOW_ON_USER_GESTURE },
  { "wsc", ALLOW_ON_USER_GESTURE },
  { "wsf", ALLOW_ON_USER_GESTURE },
  { "wsh", ALLOW_ON_USER_GESTURE },
  { "xbap", DANGEROUS },
#elif defined(OS_MACOSX)
  { "bash", ALLOW_ON_USER_GESTURE },
  { "command", ALLOW_ON_USER_GESTURE },
  { "csh", ALLOW_ON_USER_GESTURE },
  { "ksh", ALLOW_ON_USER_GESTURE },
  { "pkg", ALLOW_ON_USER_GESTURE },
  { "sh", ALLOW_ON_USER_GESTURE },
  { "shar", ALLOW_ON_USER_GESTURE },
  { "tcsh", ALLOW_ON_USER_GESTURE },
#elif defined(OS_ANDROID)
  { "apk", ALLOW_ON_USER_GESTURE },
  { "sh", ALLOW_ON_USER_GESTURE },
  { "shar", ALLOW_ON_USER_GESTURE },
  { "dex", ALLOW_ON_USER_GESTURE },
#elif defined(OS_POSIX)
  // TODO(estade): lengthen this list.
  { "bash", ALLOW_ON_USER_GESTURE },
  { "csh", ALLOW_ON_USER_GESTURE },
  { "deb", ALLOW_ON_USER_GESTURE },
  { "exe", ALLOW_ON_USER_GESTURE },
  { "ksh", ALLOW_ON_USER_GESTURE },
  { "rpm", ALLOW_ON_USER_GESTURE },
  { "sh", ALLOW_ON_USER_GESTURE },
  { "shar", ALLOW_ON_USER_GESTURE },
  { "tcsh", ALLOW_ON_USER_GESTURE },
#endif
};

DownloadDangerLevel GetFileDangerLevel(const base::FilePath& path) {
  base::FilePath::StringType extension(path.Extension());
  if (extension.empty())
    return NOT_DANGEROUS;
  if (!IsStringASCII(extension))
    return NOT_DANGEROUS;
#if defined(OS_WIN)
  std::string ascii_extension = WideToASCII(extension);
#elif defined(OS_POSIX)
  std::string ascii_extension = extension;
#endif

  // Strip out leading dot if it's still there
  if (ascii_extension[0] == base::FilePath::kExtensionSeparator)
    ascii_extension.erase(0, 1);

  for (size_t i = 0; i < arraysize(g_executables); ++i) {
    if (LowerCaseEqualsASCII(ascii_extension, g_executables[i].extension))
      return g_executables[i].level;
  }
  return NOT_DANGEROUS;
}

static const char* kExecutableWhiteList[] = {
  // JavaScript is just as powerful as EXE.
  "text/javascript",
  "text/javascript;version=*",
  "text/html",
  // Registry files can cause critical changes to the MS OS behavior.
  // Addition of this mimetype also addresses bug 7337.
  "text/x-registry",
  "text/x-sh",
  // Some sites use binary/octet-stream to mean application/octet-stream.
  // See http://code.google.com/p/chromium/issues/detail?id=1573
  "binary/octet-stream"
};

static const char* kExecutableBlackList[] = {
  // These application types are not executable.
  "application/*+xml",
  "application/xml"
};

bool IsExecutableMimeType(const std::string& mime_type) {
  for (size_t i = 0; i < arraysize(kExecutableWhiteList); ++i) {
    if (net::MatchesMimeType(kExecutableWhiteList[i], mime_type))
      return true;
  }
  for (size_t i = 0; i < arraysize(kExecutableBlackList); ++i) {
    if (net::MatchesMimeType(kExecutableBlackList[i], mime_type))
      return false;
  }
  // We consider only other application types to be executable.
  return net::MatchesMimeType("application/*", mime_type);
}

}  // namespace download_util
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// this file defines the otbCommonTest for the test driver
// and all it expects is that you have a function called RegisterTests
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
#include "otbTestMain.h"

void RegisterTests()
{
REGISTER_TEST(otbAlignImageToPath);
REGISTER_TEST(otbDrawPathList);
REGISTER_TEST(otbDrawPathListTracerLignes);
REGISTER_TEST(otbDrawPathDessinCarre);
REGISTER_TEST(otbDrawPathAlign);
REGISTER_TEST(otbComplexMomentImage);
REGISTER_TEST(otbHuImage);
REGISTER_TEST(otbFlusserImage);
REGISTER_TEST(otbComplexMomentPathNew);
REGISTER_TEST(otbComplexMomentPath);
REGISTER_TEST(otbComplexMomentPathFloat);
REGISTER_TEST(otbHuPathNew);
REGISTER_TEST(otbHuPath);
REGISTER_TEST(otbFlusserPathNew);
REGISTER_TEST(otbFlusserPath);
REGISTER_TEST(otbOrientationPathNew);
REGISTER_TEST(otbOrientationPath);
REGISTER_TEST(otbCompacityPathNew);
REGISTER_TEST(otbCompacityPathCircle);
REGISTER_TEST(otbCompacityPathSquare);
REGISTER_TEST(otbCompacityPathRectangle);
REGISTER_TEST(otbTouziEdgeDetectorNew);
REGISTER_TEST(otbTouziEdgeDetector);
REGISTER_TEST(otbTouziEdgeDetectorDirection);
REGISTER_TEST(otbLineDetectorBaseNew);
REGISTER_TEST(otbLineRatioDetectorNew);
REGISTER_TEST(otbLineRatioDetectorLinear);
REGISTER_TEST(otbLineRatioDetectorLinearDirection);
REGISTER_TEST(otbLineRatioDetector);
REGISTER_TEST(otbLineCorrelationDetectorNew);
REGISTER_TEST(otbLineCorrelationDetectorLinear);
REGISTER_TEST(otbLineCorrelationDetectorLinearDirection);
REGISTER_TEST(otbLineCorrelationDetector);
REGISTER_TEST(otbAssociativeSymmetricalSumNew);
REGISTER_TEST(otbAssociativeSymmetricalSum);
REGISTER_TEST(otbAssymmetricFusionOfLineDetectorNew);
REGISTER_TEST(otbAssymmetricFusionOfLineDetector);
REGISTER_TEST(otbHarrisImage);
REGISTER_TEST(otbMultiplyByScalarImageFilterTest);
REGISTER_TEST(otbThresholdImageToPointSetTest);
REGISTER_TEST(otbHarrisToPointSet);
REGISTER_TEST(otbPixelSuppressionByDirectionNew);
REGISTER_TEST(otbPixelSuppressionByDirection);
REGISTER_TEST(otbFillGapsFilterNew);
REGISTER_TEST(otbLocalHoughNew);
REGISTER_TEST(otbLocalHough);
REGISTER_TEST(otbLocalHoughDraw);
REGISTER_TEST(otbExtractSegmentsNew);
REGISTER_TEST(otbExtractSegments);
}
<commit_msg>otbLogPolarResampleImageFilter : implémentation de la classe + tests<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

// this file defines the otbCommonTest for the test driver
// and all it expects is that you have a function called RegisterTests
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#include <iostream>
#include "otbTestMain.h"

void RegisterTests()
{
REGISTER_TEST(otbAlignImageToPath);
REGISTER_TEST(otbDrawPathList);
REGISTER_TEST(otbDrawPathListTracerLignes);
REGISTER_TEST(otbDrawPathDessinCarre);
REGISTER_TEST(otbDrawPathAlign);
REGISTER_TEST(otbComplexMomentImage);
REGISTER_TEST(otbHuImage);
REGISTER_TEST(otbFlusserImage);
REGISTER_TEST(otbComplexMomentPathNew);
REGISTER_TEST(otbComplexMomentPath);
REGISTER_TEST(otbComplexMomentPathFloat);
REGISTER_TEST(otbHuPathNew);
REGISTER_TEST(otbHuPath);
REGISTER_TEST(otbFlusserPathNew);
REGISTER_TEST(otbFlusserPath);
REGISTER_TEST(otbOrientationPathNew);
REGISTER_TEST(otbOrientationPath);
REGISTER_TEST(otbCompacityPathNew);
REGISTER_TEST(otbCompacityPathCircle);
REGISTER_TEST(otbCompacityPathSquare);
REGISTER_TEST(otbCompacityPathRectangle);
REGISTER_TEST(otbTouziEdgeDetectorNew);
REGISTER_TEST(otbTouziEdgeDetector);
REGISTER_TEST(otbTouziEdgeDetectorDirection);
REGISTER_TEST(otbLineDetectorBaseNew);
REGISTER_TEST(otbLineRatioDetectorNew);
REGISTER_TEST(otbLineRatioDetectorLinear);
REGISTER_TEST(otbLineRatioDetectorLinearDirection);
REGISTER_TEST(otbLineRatioDetector);
REGISTER_TEST(otbLineCorrelationDetectorNew);
REGISTER_TEST(otbLineCorrelationDetectorLinear);
REGISTER_TEST(otbLineCorrelationDetectorLinearDirection);
REGISTER_TEST(otbLineCorrelationDetector);
REGISTER_TEST(otbAssociativeSymmetricalSumNew);
REGISTER_TEST(otbAssociativeSymmetricalSum);
REGISTER_TEST(otbAssymmetricFusionOfLineDetectorNew);
REGISTER_TEST(otbAssymmetricFusionOfLineDetector);
REGISTER_TEST(otbHarrisImage);
REGISTER_TEST(otbMultiplyByScalarImageFilterTest);
REGISTER_TEST(otbThresholdImageToPointSetTest);
REGISTER_TEST(otbHarrisToPointSet);
REGISTER_TEST(otbPixelSuppressionByDirectionNew);
REGISTER_TEST(otbPixelSuppressionByDirection);
REGISTER_TEST(otbFillGapsFilterNew);
REGISTER_TEST(otbLocalHoughNew);
REGISTER_TEST(otbLocalHough);
REGISTER_TEST(otbLocalHoughDraw);
REGISTER_TEST(otbExtractSegmentsNew);
REGISTER_TEST(otbExtractSegments);
REGISTER_TEST(otbForwardFourierMellinTransformImageFilterNew);
}
<|endoftext|>


<commit_before><commit_msg>Make spacing between "theme" buttons same as spacing between "browsing data" buttons.<commit_after><|endoftext|>


<commit_before>#include "PackPNG.h"
#include "Lzma.h"
#include "typedef.h"

#include <ee/SettingData.h>
#include <ee/Config.h>
#include <ee/ImageLoader.h>
#include <ee/Exception.h>
#include <ee/ImageData.h>
#include <ee/Image.h>
#include <ee/ImageSymbol.h>
#include <ee/Snapshoot.h>
#include <ee/ImageVerticalFlip.h>

#include <easyimage.h>

namespace erespacker
{

PackPNG::PackPNG(bool png8)
	: m_buffer(NULL)
{
	m_type = png8 ? TT_PNG8 : TT_PNG4;
}

PackPNG::~PackPNG()
{
	Clear();
}

void PackPNG::Load(const std::string& filepath)
{
	Clear();

	ee::SettingData& data = ee::Config::Instance()->GetSettings();
	bool ori_clip_cfg = data.open_image_edge_clip;
	data.open_image_edge_clip = false;
	bool ori_alpha_cfg = data.pre_multi_alpha;
	data.pre_multi_alpha = false;

	int w, h, c, f;
	uint8_t* buf = ee::ImageLoader::FileToPixels(filepath, w, h, c, f);

	data.open_image_edge_clip = ori_clip_cfg;
	data.pre_multi_alpha = ori_alpha_cfg;

	m_width = w;
	m_height = h;
	m_buffer = buf;
	if (c != 4) {
		throw ee::Exception("PackPNG::Load: image is not rgba.");
	}

	if (m_type == TT_PNG4) {
		GenPng4();
	}
}

void PackPNG::Store(const std::string& filepath, float scale) const
{
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str(), std::ios::binary);
	std::locale::global(std::locale("C"));

	if (scale == 1) {
		Store(fout, m_buffer, m_width, m_height);
	} else {
		size_t sz = m_width * m_height * 4;
		uint8_t* buf = new uint8_t[sz];
		memcpy(buf, m_buffer, sz);

		ee::ImageData img_data(buf, m_width, m_height, 4);
		ee::Image img(&img_data);
		ee::ImageSymbol symbol(&img, "");

		int width = static_cast<int>(m_width * scale),
			height= static_cast<int>(m_height * scale);
		ee::Snapshoot ss;
		uint8_t* buffer = ss.OutputToMemory(&symbol, false, scale);
		RevertAndStore(fout, buffer, width, height);
		delete[] buffer;
	}

	fout.close();
}

void PackPNG::RevertAndStore(std::ofstream& fout, uint8_t* buffer, int width, int height) const
{
	ee::ImageVerticalFlip revert(buffer, width, height);
	uint8_t* buf_revert = revert.Revert();
	Store(fout, buf_revert, width, height);
	delete[] buf_revert;
}

void PackPNG::Clear()
{
	delete[] m_buffer, m_buffer = NULL;
}

static inline int
_round(int c) {
	c = (c + 7 > 0xff) ? (0xff) : (c + 7);
	return c >> 4;
}

// todo
void PackPNG::GenPng4()
{
	int size = m_width * m_height;
	for (int i = 0; i < size; i += 4)
	{
		int r = _round(m_buffer[i]);
		int g = _round(m_buffer[i+1]);
		int b = _round(m_buffer[i+2]);
		int a = _round(m_buffer[i+3]);
	}
}

void PackPNG::Store(std::ofstream& fout, uint8_t* buffer,
					int width, int height) const
{
	int buf_sz = width * height * 4;
	if (m_compress)
	{
		size_t sz = sizeof(int8_t) + sizeof(int16_t) * 2 + buf_sz;
		uint8_t* buf = new uint8_t[sz];
		uint8_t* ptr = buf;

		memcpy(ptr, &m_type, sizeof(int8_t));
		ptr += sizeof(int8_t);
		memcpy(ptr, &width, sizeof(int16_t));
		ptr += sizeof(int16_t);
		memcpy(ptr, &height, sizeof(int16_t));
		ptr += sizeof(int16_t);
		memcpy(ptr, buffer, buf_sz);
		ptr += buf_sz;

		uint8_t* dst = NULL;
		size_t dst_sz;
		Lzma::Compress(&dst, &dst_sz, buf, sz);
		delete[] buf;

		if (dst_sz > 0) {
			fout.write(reinterpret_cast<const char*>(&dst_sz), sizeof(uint32_t));
			fout.write(reinterpret_cast<const char*>(dst), dst_sz);
			delete[] dst;
		}
	}
	else
	{
		int sz = 0;
		sz += sizeof(int8_t);	// type
		sz += sizeof(int16_t);	// width
		sz += sizeof(int16_t);	// height
		sz += buf_sz;			// buf
		sz = -sz;
		fout.write(reinterpret_cast<const char*>(&sz), sizeof(int32_t));

		fout.write(reinterpret_cast<const char*>(&m_type), sizeof(int8_t));
		fout.write(reinterpret_cast<const char*>(&width), sizeof(int16_t));
		fout.write(reinterpret_cast<const char*>(&height), sizeof(int16_t));
		fout.write(reinterpret_cast<const char*>(buffer), buf_sz);
	}
}

}<commit_msg>[FIXED] pack png with channels is 3<commit_after>#include "PackPNG.h"
#include "Lzma.h"
#include "typedef.h"

#include <ee/SettingData.h>
#include <ee/Config.h>
#include <ee/ImageLoader.h>
#include <ee/Exception.h>
#include <ee/ImageData.h>
#include <ee/Image.h>
#include <ee/ImageSymbol.h>
#include <ee/Snapshoot.h>
#include <ee/ImageVerticalFlip.h>

#include <easyimage.h>

namespace erespacker
{

PackPNG::PackPNG(bool png8)
	: m_buffer(NULL)
{
	m_type = png8 ? TT_PNG8 : TT_PNG4;
}

PackPNG::~PackPNG()
{
	Clear();
}

void PackPNG::Load(const std::string& filepath)
{
	Clear();

	ee::SettingData& data = ee::Config::Instance()->GetSettings();
	bool ori_clip_cfg = data.open_image_edge_clip;
	data.open_image_edge_clip = false;
	bool ori_alpha_cfg = data.pre_multi_alpha;
	data.pre_multi_alpha = false;

	int w, h, c, f;
	uint8_t* buf = ee::ImageLoader::FileToPixels(filepath, w, h, c, f);

	data.open_image_edge_clip = ori_clip_cfg;
	data.pre_multi_alpha = ori_alpha_cfg;

	m_width = w;
	m_height = h;
	if (c == 3) {
		m_buffer = new uint8_t[w * h * 4];
		uint8_t *src = buf, *dst = m_buffer;
		for (int i = 0, n = w * h; i < n; ++i) {
			memcpy(dst, src, sizeof(uint8_t) * 3);
			src += 3;
			dst += 3;
			*dst = 255;
			dst += 1;
		}
	} else if (c == 4) {
		m_buffer = buf;
	} else {
		throw ee::Exception("PackPNG::Load: error channels %d.", c);
	}

	if (m_type == TT_PNG4) {
		GenPng4();
	}
}

void PackPNG::Store(const std::string& filepath, float scale) const
{
	std::locale::global(std::locale(""));
	std::ofstream fout(filepath.c_str(), std::ios::binary);
	std::locale::global(std::locale("C"));

	if (scale == 1) {
		Store(fout, m_buffer, m_width, m_height);
	} else {
		size_t sz = m_width * m_height * 4;
		uint8_t* buf = new uint8_t[sz];
		memcpy(buf, m_buffer, sz);

		ee::ImageData img_data(buf, m_width, m_height, 4);
		ee::Image img(&img_data);
		ee::ImageSymbol symbol(&img, "");

		int width = static_cast<int>(m_width * scale),
			height= static_cast<int>(m_height * scale);
		ee::Snapshoot ss;
		uint8_t* buffer = ss.OutputToMemory(&symbol, false, scale);
		RevertAndStore(fout, buffer, width, height);
		delete[] buffer;
	}

	fout.close();
}

void PackPNG::RevertAndStore(std::ofstream& fout, uint8_t* buffer, int width, int height) const
{
	ee::ImageVerticalFlip revert(buffer, width, height);
	uint8_t* buf_revert = revert.Revert();
	Store(fout, buf_revert, width, height);
	delete[] buf_revert;
}

void PackPNG::Clear()
{
	delete[] m_buffer, m_buffer = NULL;
}

static inline int
_round(int c) {
	c = (c + 7 > 0xff) ? (0xff) : (c + 7);
	return c >> 4;
}

// todo
void PackPNG::GenPng4()
{
	int size = m_width * m_height;
	for (int i = 0; i < size; i += 4)
	{
		int r = _round(m_buffer[i]);
		int g = _round(m_buffer[i+1]);
		int b = _round(m_buffer[i+2]);
		int a = _round(m_buffer[i+3]);
	}
}

void PackPNG::Store(std::ofstream& fout, uint8_t* buffer,
					int width, int height) const
{
	int buf_sz = width * height * 4;
	if (m_compress)
	{
		size_t sz = sizeof(int8_t) + sizeof(int16_t) * 2 + buf_sz;
		uint8_t* buf = new uint8_t[sz];
		uint8_t* ptr = buf;

		memcpy(ptr, &m_type, sizeof(int8_t));
		ptr += sizeof(int8_t);
		memcpy(ptr, &width, sizeof(int16_t));
		ptr += sizeof(int16_t);
		memcpy(ptr, &height, sizeof(int16_t));
		ptr += sizeof(int16_t);
		memcpy(ptr, buffer, buf_sz);
		ptr += buf_sz;

		uint8_t* dst = NULL;
		size_t dst_sz;
		Lzma::Compress(&dst, &dst_sz, buf, sz);
		delete[] buf;

		if (dst_sz > 0) {
			fout.write(reinterpret_cast<const char*>(&dst_sz), sizeof(uint32_t));
			fout.write(reinterpret_cast<const char*>(dst), dst_sz);
			delete[] dst;
		}
	}
	else
	{
		int sz = 0;
		sz += sizeof(int8_t);	// type
		sz += sizeof(int16_t);	// width
		sz += sizeof(int16_t);	// height
		sz += buf_sz;			// buf
		sz = -sz;
		fout.write(reinterpret_cast<const char*>(&sz), sizeof(int32_t));

		fout.write(reinterpret_cast<const char*>(&m_type), sizeof(int8_t));
		fout.write(reinterpret_cast<const char*>(&width), sizeof(int16_t));
		fout.write(reinterpret_cast<const char*>(&height), sizeof(int16_t));
		fout.write(reinterpret_cast<const char*>(buffer), buf_sz);
	}
}

}<|endoftext|>